I was confused by this as well, until I figured it out...
He's not talking about about CONTENT sharing a tail- He's talking about two association lists sharing their ENTIRE STRUCTURE...
Let's say you have a database made of key-value pairs and then need to fork it. The fork only contains one difference- One of the keys has to have a different value.
If the database is in a hash table, you're gonna have to clone the entire existing hash table. (They could share content, but the table, itself, needs to be a clone)
If the database is in an assoc list, the fork with the changed key can just have an extra pair for the new key, but then it can "borrow" the entire rest of the data from the other database. So virtually the entire database is shared between the two forks.
I don't know if I'd actually write something like that in a real program... not because of performance (which isn't good, but merely by a constant factor, so it's not an issue IMHO) but because the errsafe could hide other errors...
that said, the performance, in theory, might actually be better in some cases: lists (but not atoms) will be processed with one less condition.
First of all, this is a nice piece of work, rincewind- I'm going to have to think a while to decide on the merits of this approach for my personal use. I like the fiendish use of 'zap :-)
FYI- If any of you are confused by the extra 2 in rincewinds code, it is NOT one of the numbers to be added. The currying code just requires it because of the impedance mismatch between variable arguments and currying. The Haskell core doesn't have variable argument support, so this is not an issue in Haskell.
Keep in mind that "On Lisp" covers currying, whereas arc currently does not. I assume this is because pg is still trying to decide on a currying approach, whether it will be implicit currying, syntax-based currying, or function-based currying.
Here's an awesome variant based on your approach I'm probably going to try and implement soon, now that I've thought of it- Have a number in the function position (currently an error) initiate currying!
For example:
> (2 +)
#<procedure>
The two here, as in rincewind's code, means that the curried version of '+ should resolve to the result after two parameters are passed in.
> ((2 +) 7)
#<procedure>
> (((2 +) 7) 5)
12
> (map ((2 +) 7) '(1 2 3))
(8 9 10)
> (map (2.+ 7) '(1 2 3))
(8 9 10)
(these next ones assume my mods to the intrasymbol syntax are in place http://arclanguage.org/item?id=7644)
> (map 2.+.7 '(1 2 3))
(8 9 10)
(for those of you wondering why the "2" is necessary)
> (map 3.+.7 '(1 2 3))
(#<procedure> #<procedure> #<procedure>)
> (map [_ 100] (map 3.+.7 '(1 2 3)))
(108 109 110)
Note that the "integers in function position" concept could also work with implicit currying- In that case, "2.+" would simply convert '+ into the dual arity version of '+. The examples would stay the same- However, in that case the integer could of course be ommited for fixed arity functions.
It's an interesting idea, but I'm not sure your use of ":" fits in well with the current concept of colon-based composition.
I would like to see this issue approached a little differently. I think we should:
1. Make "." and "!" work in a nested fashion (as I implemented in http://arclanguage.org/item?id=7644)
2. Allow the reader to treat a parenthesized item as an item that supports intrasymbol syntax.
Then, you could write the following to resolve the same way as your example:
'(a (b c)).1.0
I'll probably try implementing something that can do this sooner or later...
(defm <base>compose ((t a int) (t b int))
(annotate 'composed-int
(cons a b)))
(defm <base>compose ((t a composed-int) (t b int))
(annotate 'composed-int
(cons a b)))
Then we can redefine the call* table as an overloading of the <base>call function:
(defm <base>call ((t l cons) (t v composed-int))
(let (first second) (rep v)
((l first) second)))
> 2. Allow the reader to treat a parenthesized item as an item that supports intrasymbol syntax.
This is probably going to conflict with (a . d) format
Could be you don't have unix permissions on port 80. I think it's common on Unices for non root users to have limited access to low numbered ports. Maybe try running mzscheme with sudo?
not a bad idea, but it is a limited solution to the problem, since it won't prevent you from creating a new global 'cplx-fun. Plus, it places code dealing with a crosscutting concern right inside the macro. That feels grungy to me.
If I think about the problem my preferred solution would be a function called 'lock-name. Right after defining 'cplx-fun you would call:
(lock-name 'cplx-fun)
Then, whenever this name is redefined, whether locally or globally, it would give a warning when the code is run. There would also be an 'unlock-name function for supressing the warning. This way, you could write macros without worrying about this issue but still had a way to guard against it.
Of course, I might be missing part of the problem or my solution may have its own problems that I don't see right now.
Good luck on your multiprocess library BTW- I think it could be a useful tool. I may look into it sometime soon, if it can be adapted to work with the base arc2.tar.
err, it's not a library, it's a full implementation of Arc.
I'll probably also include some method of locking the global (and only the global) but only with a lot of big warning signs around the locking function, saying that this should be used only if efficiency is a real concern. Also, my intended lock is a true lock: no redefinition of the <edit>global</edit> at all.
Also, ssyntax could potentially help with the apparently long symeval!foo form; say: <>foo maybe?