Is there any sympathy for this?
There is; I agree that this is a desirable thing to have in the
language. However, I fear that the addition would be far from trivial,
unfortunately. Here some big issues that I see with implementing this
primitive:
*1) Primitives are not first-class values in NetLogo*
I don't know what the opposition is to the proposal in the ticket that
Seth linked, but if it involves not wanting to use tasks, this first
item should demonstrate why this problem essentially /has to//be/ solved
with tasks.
First, we should decide what our hypothetical syntax for this primitive
should be. Maybe something like this:
`apply first ["apples"] ; should give us "a"`
This would be problematic in the current version of NetLogo, because
this would be interpreted as `apply (first ["apples"])` which is
presumably an error, or maybe results in `"apples"`—either way,
something undesirable. NetLogo's parsing rules mean that we would need
new syntax for converting a primitive into a first-class primitive of
some sort. Maybe something like this:
`apply (first) ["apples"]`
This syntax has the benefit of seeming consistent in a way with stuff
like `first (word "apples" "oranges") "bananas"`, where the parentheses
tell the primitive (`word`) to stop gobbling up terms and treating them
as arguments. However, this would create parsing problems in the case
of something like `apply (no-turtles) []`, since `(no-turtles)` is
already a perfectly valid NetLogo expression.
We could try this:
`apply [first] ["apples"]`
Might NetLogo get confused, trying to treat `[first]` as a list
literal? Maybe. Should the argument be forced to be a command
block/reporter block instead? If so, then we probably need an `apply`
*and* an `apply-report`, for command blocks and reporter blocks,
respectively. But that's still a problem, because command
blocks/reporter blocks can't take arguments, so they seem like the wrong
fit for this problem. Should we change them to take arguments? Or do
we add yet another meaning for the square brackets, specifically for
`apply`?
Maybe we could invent some totally new syntax for this (and somehow not
break old models, by using characters for this syntax that already
aren't acceptable characters to have in a NetLogo identifier—few as they
are), but, even if a good syntax were devised that wouldn't break old
models, the NetLogo code currently doesn't really have an internal
notion for a first-class primitive. Adding such a notion to NetLogo
would take a pretty large amount of work, and it's probably a bad change
to make, overall, given how many "first-class code" types already exist
internal to NetLogo. Instead, I think it makes a lot more sense for
`apply` to work solely on tasks. This brings us to the other big
problem I see.
*2) Not all primitive arguments are actually first class values
*
That might seem like a paradoxical statement, but I can assure you that
there's truth in what I've said!
A demonstration:
`apply (task [crt]) [1]`
So far, so good. `1` is totally a first-class value.
Ah, but `crt` can take a second argument. Let's try that out:
`apply (task [crt]) [1 [ pen-down ]]`
Okay, now we're in trouble. `crt`'s second argument is a command
block. Command blocks aren't first-class; they can only be passed to
certain primitives, and they can't be stored in `let`s or put into
lists. The same goes for reporter blocks and "reference types" (like
what `uphill`/`downhill` take as arguments), as well as "boolean blocks"
(like the second argument to `all?`), and "number blocks" (like the
second argument to `max-one-of`).
This situation is looking very daunting to me. One solution would be to
make those things first-class values, but it sounds terrifying to me to
change so many of these old, edge-casey, crufty types all into
first-class values, and there has definitely been a push in recent years
to /move away from/ that scary conglomeration of different block types,
rather than do anything to embrace it.
The correct solution to this, I think, is probably to tear all of the
"reference type" and "<x> block" stuff out of NetLogo altogether, and
replace all instances of those with tasks. Tragically, though, this
leaves us with a proposal that appears to make sense—though other holes
could probably be poked in it—but that would require quite a bit of time
to implement.
So... I'd be interested to see `apply` make it into the language at some
point, but my main concern here is the resource cost. Furthermore, would
all the effort that would go into implementing this really be worth it
for how much the userbase benefited from it?—I think that's another good
question to have answered before tackling the addition of `apply`.
On 08/10/2015 09:42 PM, Alan Isaac wrote:
On Monday, August 10, 2015 at 6:59:01 PM UTC-4, Seth Tisue wrote:
see also https://github.com/NetLogo/NetLogo/issues/539
<https://github.com/NetLogo/NetLogo/issues/539>
I don't like the `apply` proposal as well as the `sequence` proposal,
but it points to the same issue, even if it offers a less general
solution.
The existence of the issue is the reason for proposing a new primitive.
Is there any sympathy for this?
Alan Isaac
--
You received this message because you are subscribed to the Google
Groups "netlogo-devel" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"netlogo-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.