Arc Forumnew | comments | leaders | submitlogin
Destructive list operations
1 point by stefano 5734 days ago | 14 comments
What's the standard way to name destructive operations in Arc? In Scheme it's to append '!' to the name, and in CL it's (usually) to prepend 'n'. The first is clearly not usable in Arc because of ssyntax.


3 points by drcode 5734 days ago | link

I think you'd use '=

  > (= foo '(1 2 3))
  > (= (cadr foo) 7)
  > foo
  (1 7 3)

-----

1 point by stefano 5733 days ago | link

I didn't have in mind assignment. I was thinking at functions such as append that desctructively use their arguments. In Scheme such a function is called "append!", in CL "nconc" but in Arc there is no standard naming.

-----

1 point by absz 5733 days ago | link

In that case, you want the zap macro:

  (zap join x '(a b c))
zap turns into, more or less,

  (= x (join x '(a b c)))
Its signature is (op place . args), so all the arguments are optimized.

However, we do need naming conventions; zap, though multipurpose, is still not completely general. And there are no good ones, unfortunately.

-----

1 point by stefano 5732 days ago | link

The problem is that when using join with zap you need to cons a lot of memory, while a destructive join would not cons up memory, it would just traverse the list setting the right cdrs. Probably the expression "recycling operations" describes better what I wanted to say, because operations such as nconc reuse the memory of their arguments.

-----

1 point by almkglor 5733 days ago | link

my suggestion: D!join

-----

1 point by stefano 5732 days ago | link

This would mean to have a huge hash table containing all destructive operations, and that a lookup in that table would be necessary just to call a function. A namespace system (such that of CL) would be the right thing, because names in such a system are resolved before runtime.

(d::join ...)

The character #\: has been already taken, though. Maybe a good name would be (d/join ...). What do you think?

-----

1 point by almkglor 5731 days ago | link

Depends. If we accept the modification in http://arclanguage.com/item?id=7451 , it would be possible to make modules into a macro, and D!join would be resolved during macro-expansion into a 'uniq that can be 'symeval -ed to the destructive join operation.

-----

1 point by absz 5732 days ago | link

/ would be problematic, though, as we already have things like w/uniq, w/stdin, /, etc. I like Scheme's convention, so what about

  (add-ssyntax-bottom ; Or perhaps -top
    #\! (sym:string 'L #\!))
? This would allow us to use !s in the final position of a function name, e.g. join!.

-----

1 point by almkglor 5731 days ago | link

This makes:

  (join! foo bar)
into:

  ((sym:string 'join #\!) foo bar)
which doesn't seem to be what you want.

As an aside, you might want to try this on Anarki:

  (require "ssyntaxes.arc")
  (def foo! (x)
    (= (cdr x) 42)
    x)
  (= bar '(1 2))
  (foo! bar)

-----

1 point by absz 5731 days ago | link

That's what I would have thought, but it appeared to work. Though it may only have worked because of your second observation. And given that, I will repeat my desire for the destructive! custom. I like it because it doesn't interfere with any name (e.g. how alist could be association list or the "is the object a list?" predicate [though that's a bad example, you get the idea]), it has seen use in multiple languages, and it pretty clearly says what it means (assuming you want to encourage functional programming, as I think we do).

-----

2 points by almkglor 5731 days ago | link

I suggest running a poll on this - of course, pg probably won't care either way, but we can integrate his code into Anarki next time he bothers to release an update, ne?

I think this convention is good; I'm just somewhat concerned with the fact that foo!bar is plenty overloaded.

edit: IIRC this has been suggested a few times before already, so I think there'll be good support for this - but it means we will then have to formally standardize the ssyntaxes too.

-----

2 points by stefano 5731 days ago | link

Poll added :)

-----

1 point by almkglor 5734 days ago | link

None yet. tokipin's idea here is approximately what I had in mind for SNAP, where I might possibly define a module system accessible using module!export syntax, but really the problem is the interaction between modules and types as well as modules and macros.

-----

1 point by tokipin 5734 days ago | link

i can't speak about any standards, but the following syntax might not be bad:

  (d!car '(1 2 3))
the setup is:

  (def d (op)
      (eval op))

-----