Since this is the Arc forum, I can link you to the Arc solution: http://arclanguage.org/item?id=3477 . It's a general way to set up infix notation for arithmetic, etc.
Just FYI, 'infix is not a keyword. (Arc doesn't really have keywords in the same way as other languages, the closest it has are words like 'quote, 'fn, and 'if, which need to be dealt with explicitly in the compiler. Things like 'def and '= which look like keywords in other languages are actually macros, allowing them to be (re)defined by the user inside of arc.)
Also note that there is an infix syntax (besides the custom DSL solution mentioned above), which would probably do what you want. (See http://arclanguage.org/item?id=2610.) You can
Note that using infix.arc, you don't even need an 'infix keyword around infix math. (This works as long as the object in functional position is a number.) Also note that the syntax of function calls is still exactly the same, it is just infix notation that is implemented.
Because infix notation doesn't interfere with the rest of the language, it actually used to be loaded by default on Anarki, but it was removed because it incurs a fairly hefty runtime overhead, even when using normal (prefix) math.
Your problem is that tcp-connect returns multiple values; not a list, but multiple values. What you need to do is extract the two values into a list, and return them. This can be done via mzscheme's call-with-values procedure, takes two functions; the first is called with no arguments, and generates multiple values; the second is called on all of the values. Thus, you want, if memory serves, the entirely untested
(xdef 'tcp-connect
(lambda (host port . rest)
(call-with-values
(lambda () (apply tcp-connect host port rest))
list)))
Give that a shot, and see if it works.
I never knew that mzscheme had multiple return values… learn something new every day, I guess!
Why? because there isn't that much in lisp/scheme/arc that comes naturally to me :).
Not sure about how to go about pushing something on something else. Never been in an environment where we worked with cvs or git or anything. Solitary scientists :)
Ouch, I hadn't thought of that. But I just tested this, and it appears that ac.scm runs the translation step after the xdefed functions return, so we get a valid Arc list back. Saved by the bell, so to speak :)
NewLISP has been discussed before on these fora (such as at http://arclanguage.org/item?id=244), and in fact you once brought it up yourself (http://arclanguage.org/item?id=2887). You may recall that it was roundly panned by many people (myself included). Summarizing these threads, here are two of the main reasons:
1. One-reference-only storage. This means that something like (cdr lst) must copy the entire list, makes it impossible to create cyclic data structures, etc. As a consequence of this, variables are not passed by reference.
2. Dynamic binding/lack of closures (and continuations). This is one of the worst, in my view; I find dynamic binding confusing, opaque, and (potentially) bug-prone. It may well have its uses, but not as the default.
The general workaround for these is the "context". This appears (I am not an expert) to be a rudimentary module system that works by prefixing defined and referenced symbols by context-name:, unless they are already so prefixed. To pass something by reference, you must pass in its name (such as 'xs), rather than just the value (such as xs). You must, however, take care to prevent variable capture (!), and wrap your names in contexts. This is how lexical binding is simulated.
There are other, smaller issues that people have, and there are certainly things it gets right (e.g. it appears to have regular expressions). But they are eclipsed by the major flaws outlined above.
Not quite. It works in the toplevel because doing (def name args ...) is effectively to (= name (fn args ...)); this establishes a global, not a lexical, binding. Using let/with/withs adds a lexical binding, and since functions (or "closures") close over their scopes, they can't get at functions defined at the same time. Thus, you need to use withs. Observe:
That implies that at the top level, the order in which I define my functions (which use each other) doesn't matter..
nice! Then I can group them in a way that is more sensible for humans.
Anyway, the program is now far enough that I've a critter running around the field and filling its memory with associations between the things it encounters. Next stop is to let it learn what is edible and to let it steer itself based on its observations :).
That sounds like a really good idea. It might be nice to have some sort of caching mechanism, but it's nice when you want to try something (e.g. the n-back game posted recently).
In previous Lisps if you wanted to create a local variable you had to do it explicitly with a let. In Arc we were planning to let users declare local variables implicitly, just by assigning values to them. This turns out not to work, and the problem comes from an unforseen quarter: macros.
If you're going to declare local variables implicitly, you have to decide what the scope of the new variable will be. We decided we would make new variables local to blocks: a local variable created implicitly by assignment would have a scope that extended to the nearest enclosing do (Arc's progn).
...
What convinced us to toss it was not a technical problem but a social one. In a language with implicit local variables and macros, you're always tripping over unexpected lexical contours. You don't want to create new lexical contours without announcing it. But a lot of macros that don't look like blocks in the call expand into blocks. So we provided a second block operator, called justdo, which was like do but didn't create a new lexical contour (i.e. it is Common Lisp progn), and this is what you were supposed to use in macroexpansions.
The trouble was, I kept forgetting and using do instead. And I was thereby writing utilities with the worst sort of bug: the kind that might not show up for years, and only then in someone else's code.
...
This problem is not limited to Lisp. Macros and implicit local variables just don't seem to work well together. Meaning that any language that already has implicit local variables will run into trouble if they try to add macros.
----------
Maybe your "explicit var" would work, but it might just put the problem back from the other direction, so to speak. Perhaps if you give macros some form of "lexical hygiene" (yeah, yeah, hygiene bad, etc.)... How does Goo do it?
I can't get it to work because the sound functionality relies on Linux (and specifically, I think, KDE); I'm on OS X, and (a) I don't have the "play" command (well, I do, but only because I have TextMate; it's nonstandard), (b) I don't have a "/usr/share/sounds" directory, and (c) if I did, I still wouldn't have sounds such as "KDE_Beep_Beep.wav". Other than that, it appears to work.
Ack, I missed that :) It's a pity, though, as it's almost not. I'll probably tinker with that line to make it work on my machine, and that should be all it takes. Ah well.
My understanding is that ssyntax can only be part of symbols, so you wouldn't be able to write :(a b c). At any rate, I think the idea of using it is to ape keyword parameters in Common Lisp.
Personally, I like & and | or andf and orf, but as almkgor mentioned, | is taken for "odd" symbols (e.g. '|this is a symbol|), using just / would interfere with things like w/stdout, and using & and // would be asymmetric. In any case, having some ssyntax for andf and orf is definitely a good idea.
Taking inspiration from discreet math, we could use ∧ and ∨ as andf and orf, respectively. This would be in line with pg's current use of ~ as not. On the other hand, maybe we shouldn't make use of non-ascii characters... (or else you get APL et al)
I would say use ^ and v, but something tells me that disallowing a v in identifiers would be a bad idea (e.g.eval) ;)
My biggest problem with using Unicode is that it's often a pain to type. The Mac gets this the most right of any platform I know, but even so, it's (a) not a standard, and (b) mostly alphabetic. Which is a pity, really, since those do make the most sense.
> My biggest problem with using Unicode is that it's often a pain to type.
Agreed. We might be able to add a hook to arc-mode in emacs to make it more convenient, but reminds me even more of APL (which if I recall correctly required a custom keyboard to type).
> + might not be bad, but it's probably a little too common
I like +. While + does get used in symbols occasionally (most notably in arithmetic), I can't think of any cases where it gets used in the middle of a symbol.
EDIT: On second thought, when I use plus outside of a programming context, I usually mean and, so it might be confusing to use + as 'andf.
The problem with "adding a hook to arc-mode in emacs" is that then you alienate everyone not using Emacs. And that's a good point about + being used to mean &.
"maybe we shouldn't make use of non-ascii characters" : why not ? Characters like λ have their place in a Lisp, and I think ∧and ∨ have their place too. Anyway, such characters wouldn't be used very frequently (do you often use andf & orf ?) and could be ignored if typing them is too painful. That's better than consuming ASCII characters that sometimes fit well in symbol names, IMO.
I think it would be hilariously ironic to make non-ASCII Unicode characters part of Arc's syntax and functions.
A few proposals for giving functions new names: ☢ for atomic, ✄ for cut, ✔ for check, ⌚ for time, ⌛ for sleep, ☠ for kill-thread, ☇ for zap, ♭for flat.
But anyway, I still think they're not worth loosing an ASCII character, and using mathematical notation would be very useful. It would make code readable by people a little aware of mathematics. That is, most programers. It would be definitely better than arbitrary characters.
Why should we restrict to ASCII anyway ? I mean, a lot of symbols I use are not ASCII anymore (they are accentuated, I'm French so something like 'year is translated into 'année, not into 'annee). Sure, they're hard to type, but are they any longer than they symbol counterpart ? If you type them often, just make them a vi macro (or whatever in your favorite text editor) and you're done.
It might end up looking like APL, for sure, but I think Fortress, Sun's new language designed by Guy Steele, is going that way too. And Steele cannot be wrong :)
I don't mind non-ASCII, I mind weird non-ASCII. Even in English, we leave ASCII behind: “As I was going to the café—what fun—my naïve friend said…” It's just that I don't know of any keyboard layout that supports ∧ or ∨. I agree that they would look great, as would Fortress.
I wonder if anyone's given any though to using (La)TeX in a language? So that something like (number{\wedge}acons var) would be the same as (number∨acons var)? Or just as a nice way of typing things like Fortress? (Which I agree looks very interesting.)
I'd probably use them a lot more often if the syntax was a little easier, which is why I suggested using ssyntax for them. Currently the syntax is ((orf this that the-other) foo), and doubled starting parens feel rather strange to me.
I've been playing with this, and the other downside is that it's slow. Things are noticeably slower to load (not to run), as the ssyntax check is (a) more complex, and (b) written in Arc, not mzscheme. Other than those two things, though, it's absolutely great.
Hmm. After looking at that, as far as I can tell it can only match a word which ends in one of the strings in its dictionary. Using it to parse out middle bits would be tricky--you could try saving the string at each accept state, or something like that.