One of Snap!’s claims to greatness is “first class everything’’. Costumes, sounds, commands … (virtually) everything is considered data (BTW not everybody likes it: I don't want everything first class!!!). One implication thereof is that list items may belong to many different types, perhaps even within the same list. And efficient list processing is often promoted by them being sorted.
So here is my question: does Snap! provide an ordering (or ranking) function to help sort any list of items? Or how can one be constructed?
The function (let’s call it: BEFORE?) should satisfy all of the following criteria:
For any two items A and B (of any data type, or types!) either
shall report TRUE - and only one of these three!
For any three items A, B, and C,
What’s wrong with ?
An obvious candidate would have been (or ), since it will rank various data types … but not all. E.g.:
When lists are compared, it reports a list of Booleans, so not a single TRUE or FALSE;
When commands, reporters or predicates are compared, and arguments have been filled out, it stops working, e.g.
all report FALSE.
So is it correct to say that you don't really care if there is any sensible meaning to comparing objects of different types, as long as the return value is consistent for repeated comparisons of the same two objects? Sounds like you're asking for an ADDRESS OF primitive. I wonder how much of a security hole that would be.
By the same token one might as well question the meaning of ranking e.g. strings in alphabetical order. That “apple” is ranked before “banana” doesn’t mean it’s smaller, or larger, or better tasting. Still, whenever one would want to establish if two lists represent the same set of items, that will be much easier done if the lists are ordered, using the same, consistent, algorithm.
BTW ranking between data types is probably not too much of a problem (one could simply prescribe a ranking of data types); it’s mostly comparisons within a data type that I haven’t figured out yet (at least for sounds, commands, etc.)
I really couldn’t say. Would that be a pointer to a variable in memory? In that case, I don’t think so.
If reports FALSE (which it does) there must be some attribute (or attributes) differing between the two ringed blocks, and by which these predicates could be ranked.
I don’t think what I’m looking for poses a real threat to anything.
So … do you know which (public) parameters uniquely identify sounds, commands, reporters and predicates?
even though the formal parameter isn't used for anything.
(And I know, you're asking about <, but if I don't understand = (which has an intuitive meaning for functions), I certainly won't understand <.)
Not exactly. It'd be a pointer to an object in memory, the same thing IS IDENTICAL TO does for lists. The idea of sorting by pointer would be that you just compare the pointers as numbers. But it'd be too fragile a system; if you save and reload a project the objects might be allocated in memory in different orders.
Those two procedures have the same body and (no) formal parameters, but they do different things if you call them; they don't mean the same thing.
It doesn't bother me at all if we report False for two equivalent procedures; it's hard ever to do better, and impossible always to do better. But I don't like false positives. Indeed, it used to be that we just always reported False, which is unhelpful but not misleading. Jens changed it to go along with the metaprogramming features. As your pictures suggest, two procedures are equal iff their SPLITs are equal. I would just add a test to see if they were defined in the same environment (exactly the same, not a copy, so the test would be fast).
The question is whether you think a procedure is just its text. That would be true if we used dynamic scope. But as it is, I say those two results from make-adder aren't equal. Maybe we'll end up compromising by having IS IDENTICAL TO work the way I want for procedures.
Yeah, maybe. This is a different question from how = should behave. The latter intuitively means that the two things are interchangeable, i.e., they have the same meaning in the program, i.e., it's about values. But metaprogramming is all about syntax, about notation, and syntactic transformations are the first step in evaluation, before any (non-macro) procedures in the expression are called.
When we first thought about metaprogramming, Jens suggested that we need a new visual representation for an expression as such, rather than a procedure defined using the expression, let's say an orange ring instead of a gray ring. We eventually decided that that would confuse users, so the thing represented by a gray ring might or might not include an environment (a list of variable bindings) depending on context. We're not 100% confident that we've thought through all the implications of that idea. Maybe we should have a procedure ADT with fields body, parameters, and defining environment, and then you could take a body and associate it with any environment you want (if you pick one in which all the free variable names in the body are bound, of course).
So anyway, tldr, yes we're talking about metaprogramming and semantics right now! Thanks.
As a practical matter, so as not to break any existing projects, I'm leaning toward leaving = for procedures as it is, but including the defining environment in the computation for IS EQUIVALENT TO. That seems like a not-horrible way to have our cake and eat it too.
Perhaps comparing the one-way hash the export strings of each might be better. Odds of a collision are astronomically low. Only works for things that can be exported but those things (e.g closures) are a problem anyway.