Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
PrBacterio
Jul 19, 2000

McGlockenshire posted:

So if we continue this discussion on the next page, does that mean we have to go back and refactor our posts?
Yes. But we won't do it because there's a deadline and there's always time to do it later :gonk:

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Dajax.

I thought about writing something like this as an April Fools' gag, but it seems people who actually thought it was a good idea beat me to it.

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:
code:
url = "PhoneNumbers/phonenumberoverview/PhonenUmberSomething"
Inconsistent casing :argh:

and yes is really is PhonenUmber

Jonnty
Aug 2, 2007

The enemy has become a flaming star!

Suspicious Dish posted:

Dajax.

I thought about writing something like this as an April Fools' gag, but it seems people who actually thought it was a good idea beat me to it.

Do you mean that example or the project itself?

Sinestro
Oct 31, 2010

The perfect day needs the perfect set of wheels.

dwazegek posted:

code:
url = "PhoneNumbers/phonenumberoverview/PhonenUmberSomething"
Inconsistent casing :argh:

and yes is really is PhonenUmber

What if you want an obscure Blemmye king's color of brown?

Mesothelioma
Jan 6, 2009

Your favorite mineral related cancer!
Every time I look at my buddy's methods he ALWAYS returns the object Boolean instead of a regular boolean. When I ask him why he uses the object instead of the primitive he stares blankly at me.

Amarkov
Jun 21, 2010

Mesothelioma posted:

Every time I look at my buddy's methods he ALWAYS returns the object Boolean instead of a regular boolean. When I ask him why he uses the object instead of the primitive he stares blankly at me.

To be fair, and as a Java fanboy myself, this is pretty bizarre behavior on the language's side. All types are object classes and all type names should start with a capital letter. Except primitives aren't classes and their types do not start with a capital letter. Except there are also classes named after the primitives whose names do start with a capital letter, and the compiler will automatically convert between the differently cased types. Except generics must use the capital version, and null is not a permitted value for the lowercase version.

e: wow, I skipped a lot of words the first time writing that

Amarkov fucked around with this message at 21:27 on Dec 4, 2012

Freakus
Oct 21, 2000
I still remember the first time I had to chase down a null pointer exception due to the auto-unboxing of a Boolean value. Took quite a while because it "obviously" wasn't the problem.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Jonnty posted:

Do you mean that example or the project itself?

I think that example is pretty exemplary of the project as a whole.

Optimus Prime Ribs
Jul 25, 2007

Suspicious Dish posted:

Dajax.

I thought about writing something like this as an April Fools' gag, but it seems people who actually thought it was a good idea beat me to it.

Am I missing something or is this just basically just using JavaScript to execute Python code that could have just been written in JavaScript? :psyduck:

Golbez
Oct 9, 2002

1 2 3!
If you want to take a shot at me get in line, line
1 2 3!
Baby, I've had all my shots and I'm fine
edit: nm, it's astonishingly fast but is apparently AJAX

nielsm
Jun 1, 2009



Optimus Prime Ribs posted:

Am I missing something or is this just basically just using JavaScript to execute Python code that could have just been written in JavaScript? :psyduck:

Uh, I'm pretty sure what you are looking at there are some stupid examples. The Python code runs server-side and can obviously do whatever the server is able to, such as pulling stuff from a database. The interface it gives seems to be a clean RPC style where you aren't actively interacting with XHR objects or JSON or whatever, but simply pass objects into functions that happen to run at a remote.
I don't see any WTF there, rather it looks useful and well-thought out.

Also, I'm quite sure one of the basic examples made for almost any RPC system is the "add two numbers" function. Surely it's useless for any practical purpose, but it's simple and shows that calls and marshalling works.

ToxicFrog
Apr 26, 2008


Amarkov posted:

Except there are also classes named after the primitives whose names do start with a capital letter, and the compiler will automatically convert between the differently cased types.

Except when doing so would make your code cleaner, more concise, or easier to debug, in which case the compiler will just take a steaming poo poo in your mouth and tell you to convert by hand.

There are a lot of things I dislike about Java but its schizophrenia regarding objects vs primitives probably heads the list.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
It's this line of Python that's the horror:

Python code:
    dajax.assign('#result','value',str(result))
That's the simple case. The whole library is based on this, right here.

Python code:
@dajaxice_register
def flickr_save(request, new_title):
    dajax = Dajax()
    dajax.script('cancel_edit();')
    dajax.assign('#title', 'value', new_title)
    dajax.alert('Save complete using "%s"' % new_title)
    return dajax.json()
Like this.

Optimus Prime Ribs
Jul 25, 2007

nielsm posted:

Uh, I'm pretty sure what you are looking at there are some stupid examples. The Python code runs server-side and can obviously do whatever the server is able to, such as pulling stuff from a database. The interface it gives seems to be a clean RPC style where you aren't actively interacting with XHR objects or JSON or whatever, but simply pass objects into functions that happen to run at a remote.

Okay, that makes sense.
The examples they give just look like over complicating problems that could have been solved with straight-up JavaScript, but being able to do AJAX-type stuff without having to muck around with XHR objects is a plus in my book. I don't know how well that would work with frameworks like jQuery or MooTools that use their own AJAX poo poo, but supposedly it does.

Suspicious Dish posted:

Python code:
    dajax.assign('#result','value',str(result))

Well that certainly is something.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

ToxicFrog posted:

Except when doing so would make your code cleaner, more concise, or easier to debug, in which case the compiler will just take a steaming poo poo in your mouth and tell you to convert by hand.

There are a lot of things I dislike about Java but its schizophrenia regarding objects vs primitives probably heads the list.

Oh poo poo, C# has for-loop iterators that uses almost identical syntax to JavaScript... Let's deliberately pick a different syntax.

Oh poo poo, C# added Generics... Let's add them too. Oh all these generic parameters? gently caress 'em, it's all Object at runtime baby!

Oh poo poo, C# added lambda expressions, closures, and functions as first-class objects... Well, who wants to actually persist variables modified in the outer scope, that poo poo's for sperglords. We'll have our own lambdas, and blackjack, and hookers... In fact forget the lambdas. And the blackjack. Eh gently caress it, forget the whole thing.

Repeat ad-infinitum.

P.S. what's a Delegate? :v:

Doctor w-rw-rw-
Jun 24, 2008

Amarkov posted:

To be fair, and as a Java fanboy myself, this is pretty bizarre behavior on the language's side. All types are object classes and all type names should start with a capital letter. Except primitives aren't classes and their types do not start with a capital letter. Except there are also classes named after the primitives whose names do start with a capital letter, and the compiler will automatically convert between the differently cased types. Except generics must use the capital version, and null is not a permitted value for the lowercase version.

e: wow, I skipped a lot of words the first time writing that

Agreed on the part where they shouldn't have exposed the primitives in the first place.

Autoboxing, which is what you're talking about with the automatic boolean <-> Boolean, int <-> Integer, and other conversions, is necessary because primitives are values whereas classes are references (explaining for the benefit of others since you know what I'm talking about). The part where this sucks is when the object is null, the primitive conversion fails. Thing is, collections should return null, i.e. if you're using a map and the key doesn't have a corresponding value, you've got to return null. So of course collections must be able to return null - thus, they must only take objects.

That by itself can be inconvenient and might need some care, but isn't terribly horrific. What's horrific is that at some point the automatic optimization will cease to operate.

Java code:
        Integer a = 10;
        Integer b = 10;

        Log.i("A IS EQUAL TO B", "" +( a == b)); // true

        Integer c = 2000000000;
        Integer d = 2000000000;
        Log.i("C IS EQUAL TO D", "" +( c == d)); // false

So the range of input can unexpectedly blow up your program, because now your memory's all hosed.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

Suspicious Dish posted:

It's this line of Python that's the horror:

Python code:
    dajax.assign('#result','value',str(result))
That's the simple case. The whole library is based on this, right here.

Python code:
@dajaxice_register
def flickr_save(request, new_title):
    dajax = Dajax()
    dajax.script('cancel_edit();')
    dajax.assign('#title', 'value', new_title)
    dajax.alert('Save complete using "%s"' % new_title)
    return dajax.json()
Like this.
Hmm. If I'm understanding correctly, the whole library seems to be about tightly coupling the javascript front end and the django/python backend right?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

Oh poo poo, C# added Generics... Let's add them too. Oh all these generic parameters? gently caress 'em, it's all Object at runtime baby!

C# added generics about a year after Java did, and their decision to use reified generics instead of type erasure forced a huge compatibility break that was actually a serious problem for C# programmers at the time (and still noticeably bloats C# deployments). The Java developers decided they really didn't have that option give that they had a large base of deployed software that they cared about.

Ender.uNF posted:

Oh poo poo, C# added lambda expressions, closures, and functions as first-class objects...

Java added closures via anonymous inner classes in 1997, in Java 1.1. When they did so, they decided on a particular, somewhat conservative model for capturing variables. Since then, they've decided that all of their closure-like extensions should behave essentially the same way, i.e. no mutable captures.

You can fault them for these decisions, but saying the language features were added in response to C# is pretty dumb.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Mesothelioma posted:

Every time I look at my buddy's methods he ALWAYS returns the object Boolean instead of a regular boolean. When I ask him why he uses the object instead of the primitive he stares blankly at me.
So you can use null to mean 'invert the current value'!

Freakus
Oct 21, 2000

Doctor w-rw-rw- posted:

So the range of input can unexpectedly blow up your program, because now your memory's all hosed.
Incase anyone doesn't know why this is happening: it's because autoboxing uses Integer.valueOf. For optimization reasons, for certain integers Integer.valueOf will re-use another Integer object rather than creating a new one. Both a == b and c == d are comparing references, a and b are just the same reference because the integer passed into Integer.valueOf (due to autoboxing) was within Integer re-use range. From my local testing, the range is around +/- 150.

Edit: exact thresholds are +127 and -128. Yay bytes.

Freakus fucked around with this message at 02:33 on Dec 5, 2012

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

rjmccall posted:

C# added generics about a year after Java did, and their decision to use reified generics instead of type erasure forced a huge compatibility break that was actually a serious problem for C# programmers at the time (and still noticeably bloats C# deployments). The Java developers decided they really didn't have that option give that they had a large base of deployed software that they cared about.


Java added closures via anonymous inner classes in 1997, in Java 1.1. When they did so, they decided on a particular, somewhat conservative model for capturing variables. Since then, they've decided that all of their closure-like extensions should behave essentially the same way, i.e. no mutable captures.

You can fault them for these decisions, but saying the language features were added in response to C# is pretty dumb.

You know I think youre a genius dude, I wasn't serious, more lamenting the design-by-committee approach and eternally slow pace, something C++ has also long suffered from. Actually that applies to a lot of things. There's a huge benefit to having a single group make decisions (see Objective-C and LLVM from Apple and C# from MS), but it has drawbacks too.

I look at Java programmers the way people in this thread look at PHP programmers. Once you've used something much better, it's hard to go back. Java was a good step forward but it hasn't kept up with the times. I'm also starting to understand why the LISP people are so insufferable... Once you start using functions as first-class objects it just opens up whole new ways to write better code with less boilerplate, anything else seems primitive by comparison.


I'm not sure what you're referencing with the c# transition. The run times installed side by side and you can use old assemblies in the newer one so it was relatively painless. Now that we're on the other side it's a non-issue. On bloat, it only instantiates the generic template once for all reference types so I'm not sure what you are referencing. On value types it instantiates once per type to avoid the automatic box/unbox people were discussing earlier.


Edit: just to be clear, I do not think Java stole, borrowed, or did anything in response to C#, and neither language is truly new as they're in the C family and borrow from a lot of earlier work.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Doctor w-rw-rw- posted:

So the range of input can unexpectedly blow up your program, because now your memory's all hosed.
Wait, you're saying that Java shouldn't have exposed primitives and complaining about memory usage of the object versions?
A byte takes 1 byte, a Byte takes 16 bytes.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Aleksei Vasiliev posted:

Wait, you're saying that Java shouldn't have exposed primitives and complaining about memory usage of the object versions?
A byte takes 1 byte, a Byte takes 16 bytes.

What are those other 12 bytes for?

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Suspicious Dish posted:

What are those other 12 bytes for?
It's 8 bytes for the object header, 1 byte for the byte, 7 bytes for padding to align the object to a multiple of 8.
(obviously this is implementation-dependent but this is accurate for HotSpot afaik)

zeekner
Jul 14, 2007

Suspicious Dish posted:

What are those other 12 bytes for?

8 bytes for the object header, and 4 bytes for the member. The member data is allocated in 8 byte chunks, so you'll waste an additional 4 bytes that won't be used.

quote:

The class takes up at least 8 bytes. So, if you say new Object(); you will allocate 8 bytes on the heap.
Each data member takes up 4 bytes, except for long and double which take up 8 bytes. Even if the data member is a byte, it will still take up 4 bytes! In addition, the amount of memory used is increased in 8 byte blocks. So, if you have a class that contains one byte it will take up 8 bytes for the class and 8 bytes for the data, totalling 16 bytes (groan!).
Arrays are a bit more clever, at least smaller primitives get packed. I'll deal with these later.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Geekner posted:

and 4 bytes for the member
This is wrong now. Either Java 1.4 or 5 changed it so that they actually take up only the necessary space.
(good luck finding a citation for this though)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I'm not trying to rag on you; I just take these things pretty seriously because I have to appreciate the decisions and trade-offs involved. I definitely am not a huge fan of the Java language design process or its results.

Ender.uNF posted:

I look at Java programmers the way people in this thread look at PHP programmers. Once you've used something much better, it's hard to go back. Java was a good step forward but it hasn't kept up with the times. I'm also starting to understand why the LISP people are so insufferable... Once you start using functions as first-class objects it just opens up whole new ways to write better code with less boilerplate, anything else seems primitive by comparison.

Yeah, I can understand some of the language/environment issues stopping Java from delivering really good first-class functions, but yeesh.

Ender.uNF posted:

I'm not sure what you're referencing with the c# transition. The run times installed side by side and you can use old assemblies in the newer one so it was relatively painless. Now that we're on the other side it's a non-issue.

Well, I asume that they haven't stopped shipping the old system libraries. That's permanent disk footprint, and it's a pretty serious memory footprint if any applications need them. I'm aware that disk footprint isn't a traditional area of concern for Microsoft.

Ender.uNF posted:

On bloat, it only instantiates the generic template once for all reference types so I'm not sure what you are referencing. On value types it instantiates once per type to avoid the automatic box/unbox people were discussing earlier.

Well, technically there has to be metadata instantiated for different reference types so that type identity works, but you're right that code doesn't usually have to be duplicated.

Ender.uNF posted:

Edit: just to be clear, I do not think Java stole, borrowed, or did anything in response to C#, and neither language is truly new as they're in the C family and borrow from a lot of earlier work.

And to be clear on my part, I don't think there's anything wrong with C# borrowing ideas from Java†. Java got somethings right and made some mistakes, and Microsoft got to learn from both and, in so doing, make a strictly better language (at least along those dimensions).

† Which they obviously did. It's interesting to speculate about a world in which Microsoft had been able to exercise some creative control on Java and the JVM, instead of getting slapped by Sun for their trouble and then stomping off to implement their own thing. It's probably a world with massive fragmentation within the Java market and a lot less interesting language innovation from Microsoft, so it's all for the best.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Aleksei Vasiliev posted:

It's 8 bytes for the object header, 1 byte for the byte, 7 bytes for padding to align the object to a multiple of 8.
(obviously this is implementation-dependent but this is accurate for HotSpot afaik)

The auto-boxing makes it possible for the optimizer to inline these so that a "Byte" is just in a register, no?

I also assume that the "byte" primitive isn't on the heap, so it actually takes 4 or 8 bytes depending on the architecture of the system

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Aleksei Vasiliev posted:

Wait, you're saying that Java shouldn't have exposed primitives and complaining about memory usage of the object versions?
A byte takes 1 byte, a Byte takes 16 bytes.

Don't forget the cost of storing a pointer. For Byte and Boolean, which have complete caches, that's the only memory use that really matters — unless you're an idiot and calling new Byte(b) manually, boxing the hundredth byte uses no more memory than boxing the first. For char/short/int/long, the memory use matters quite a bit more — in particular, anyone working with non-ASCII text and repeatedly boxing into Character is going to be pretty wildly unhappy. But yeah, the upshot is that having an Integer field instead of an int field can be a serious memory hit — 5x on a 32-bit machine (4 byte pointer, 16 byte allocation), 8x if you're on a 64-bit machine (8 byte pointer, 24 byte allocation) — if you fall outside of the cache range.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Suspicious Dish posted:

The auto-boxing makes it possible for the optimizer to inline these so that a "Byte" is just in a register, no?

I also assume that the "byte" primitive isn't on the heap, so it actually takes 4 or 8 bytes depending on the architecture of the system

I don't know the Java calling convention, but I would guess that passing or returning a primitive byte or a boolean takes an entire register (if any are still available) or a word-sized segment of stack (otherwise). But temporary stack/register usage isn't really the important thing here; it's how much space it requires in an object or array. In both cases, it'd require some serious heroics for the optimizer to figure out that it can store a primitive instead of a boxed value, because code can intentionally make non-cached boxed values and rely on the reference inequality, so you'd have to prove that either the sinks of the reference are all address-invariant or that the sources are all guaranteed cached.

Doctor w-rw-rw-
Jun 24, 2008

Aleksei Vasiliev posted:

Wait, you're saying that Java shouldn't have exposed primitives and complaining about memory usage of the object versions?
A byte takes 1 byte, a Byte takes 16 bytes.

The horror is violated expectations, not the memory usage itself. It just feels inconsistent for Java to be a bloated memory-wasting machine except for numbers under 128, and inconsistent for a special class of non-objects. I would rather the padded walls be complete and total. I suppose I'm a bit of a purist. And even if everything is an object and there's no such thing as a primitive, there's nothing stopping the VM from figuring out how to optimize an Integer into an int behind the scenes rather than having it happen by hand.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
"There's nothing stopping the VM from <insert arbitrarily complex program transformation>" is one of those things language implementors love to hear from people who clearly haven't thought much about the problem and know nothing about the constraints on the VM.

The deep language problem is that Java can't do any useful abstraction over non-objects; any sort of generic treatment of values forces boxing. But unlike a dynamically-typed language, you can't reasonably optimize the representation of Object to make boxing cheaper — boxed ints aren't nearly common enough for that to pay off. So you have to trust the programmer to know when boxing really matters to their performance and avoid it.

1337JiveTurkey
Feb 17, 2005

Doctor w-rw-rw- posted:

The horror is violated expectations, not the memory usage itself. It just feels inconsistent for Java to be a bloated memory-wasting machine except for numbers under 128, and inconsistent for a special class of non-objects. I would rather the padded walls be complete and total. I suppose I'm a bit of a purist. And even if everything is an object and there's no such thing as a primitive, there's nothing stopping the VM from figuring out how to optimize an Integer into an int behind the scenes rather than having it happen by hand.

If you're using Integers in a manner which would typically require the creation of a new object (hashcodes, reference equality, polymorphism, null values) and depending on primitive performance not in any contract, I'm not sure what you're looking for. What are they supposed to say? "Sure there's an obvious optimization which is such low hanging fruit that it's hovering at the very threshold of the gates of Hell, but we're going to leave it to you to decide whether it's worth it."

The problem is more the behavior than it is the performance. Any situation where a boxed primitive can plausibly be stored directly in a stack frame, Java 1.7 and above will do that instead. Having two options may have made sense in 1996, but now it's straightforward to optimize out those cases. The subtly different semantics are the real issue.

Doctor w-rw-rw-
Jun 24, 2008

1337JiveTurkey posted:

If you're using Integers in a manner which would typically require the creation of a new object (hashcodes, reference equality, polymorphism, null values) and depending on primitive performance not in any contract, I'm not sure what you're looking for. What are they supposed to say? "Sure there's an obvious optimization which is such low hanging fruit that it's hovering at the very threshold of the gates of Hell, but we're going to leave it to you to decide whether it's worth it."

The problem is more the behavior than it is the performance. Any situation where a boxed primitive can plausibly be stored directly in a stack frame, Java 1.7 and above will do that instead. Having two options may have made sense in 1996, but now it's straightforward to optimize out those cases. The subtly different semantics are the real issue.

Are you arguing with me? Because I agree completely with exactly what you just said.

bobthecheese
Jun 7, 2006
Although I've never met Martha Stewart, I'll probably never birth her child.


They're a security consultant.

Also, to top it off, they do hash their passwords... with a single, unsalted md5... before sending it to the API... which is public... and doesn't escape either the username or password before running them in an SQL statement.

Not that it really matters, because none of the rest of the API requires authentication either, and you could get past the login screen just by calling the right JS function.

Goat Bastard
Oct 20, 2004

bobthecheese posted:



They're a security consultant.

Also, to top it off, they do hash their passwords... with a single, unsalted md5... before sending it to the API... which is public... and doesn't escape either the username or password before running them in an SQL statement.

Not that it really matters, because none of the rest of the API requires authentication either, and you could get past the login screen just by calling the right JS function.

There surely has to be a level where "calling yourself a security consultant" becomes "committing fraud".

1337JiveTurkey
Feb 17, 2005

Doctor w-rw-rw- posted:

Are you arguing with me? Because I agree completely with exactly what you just said.

Calling Java's inability to offer performance guarantees on Integers a coding horror is a stretch of the term at best, especially in light of the capabilities of 15 year old embedded processors. It's a plausible decision for someone who doesn't know that client-side Java on internet toasters and JavaCards is a dream at best. It's still possible to be wrong by being way too conservative in retrospect without being a horror which is basically Java's longstanding problem. I reserve the term horror for languages like PHP where there often simply isn't a good reason at all and it's clear that it wasn't thought out and not Java where there's usually a reason but it might not have been the best one in light of experience.

Pilsner
Nov 23, 2002

Mesothelioma posted:

Every time I look at my buddy's methods he ALWAYS returns the object Boolean instead of a regular boolean. When I ask him why he uses the object instead of the primitive he stares blankly at me.
There's no such thing as a primitive type in C#, typing "bool" is equal to typing the (struct, not class) "Boolean". Same with "int" and "Int32". You can't null a Boolean (nor bool).

Personally I prefer typing lower case names for types such as string, bool and such myself too, though, it just looks weird otherwise.

Adbot
ADBOT LOVES YOU

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

rjmccall posted:

In both cases, it'd require some serious heroics for the optimizer to figure out that it can store a primitive instead of a boxed value, because code can intentionally make non-cached boxed values and rely on the reference inequality, so you'd have to prove that either the sinks of the reference are all address-invariant or that the sources are all guaranteed cached.

Ah right; I didn't think of that. The reference semantics are extremely awkward for these pseudoprimitives.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply