Re: [Readable-discuss] unhappy with the current direction
Hi Alan, Sorry for not answering for so long… and thank you very much for your answers! I now have a working parser (it only took a few hours of concentration, but try to get that with two kids and some other projects competing for the free time ;) ), and I grew quite fond of your idea of a restricted inline ENLIST - after getting over the initial “gah”-phase :). I grew so fond of it that I just implemented it :) Am Donnerstag, 21. Februar 2013, 11:08:12 schrieb Alan Manuel Gloria: > We're saddened at your unhappiness with the current direction, and > glad that you have made a concrete effort at defining a suitable > alternative semantics for special indentation extensions. Not every project can be for everyone, otherwise it would have no direction. Just look at the Python Enhancement Proposals which got rejected… >From what I see, readable is focussed on making lisp more readable for >newcomers, but to my taste it loses touch with the simplicity of lisp. But >that *is* a matter of taste. Python also has a quite complex parser, and I >like it a lot. When I code in Lisp, though, I want that simplicity. > Granted, your approach can be implemented using some sort of > preprocessor separate from the core Lisp implementation; in fact, it > seems to be defined so that this is easy (hence the need to denote > single items with ".") and the preprocessor does not even need to > actually understand Lisp syntax (meaning that potentially, a single > preprocessor implementation can work with many Lisp implementations - > the Lisp implementations just need to implement n-expressions, or even > just curly-infix, both of which are far more trivial to add than > indentation). This may be considered a point in its favor, although > it certainly risks falling into the One True Implementation. That is the goal, yes: Essentially a bracket-adding preprocessor, which gives me indentation sensitive syntax while staying dead simple. The first worked out. The second not as well as I had hoped, since I’m now at about 200 lines, 170 lines if I ignore the license header :) > We hope you continue to work with or on indentation-based syntaxes for > Lisp, whether sweet-expressions, your current proposal, or some other > future notation you can develop. Definitely! (I’ve been hearing that answer echoing in my head ever since I read your mail - 1 month ago ;) ) Actually the wisp.py parser can now emit correct Lisp from indentation based syntax - though I assume I still miss a few corner cases. What it can already process is this: -- -- -- defun a (b c) let : d "i am a string do not break me!" : ; comment f ; comment ` g ; comment : h (I am in brackets do not change me) . i , ' j k . l ; comment a c defun b : n o . "second defun, with a docstring!" message "I am here" . t .. .. .. It becomes this: -- -- -- (defun a (b c) (let ( (d "i am a string do not break me!") ( ; comment (f) ; comment `(g )); comment ( (h (I am in brackets do not change me)) i))) ,'(j k) l ; comment (a c)) (defun b (n o) "second defun, with a docstring!" (message "I am here") t) .. .. .. You can get it here: https://bitbucket.org/ArneBab/wisp Best wishes, Arne -- Unpolitisch sein heißt politisch sein, ohne es zu merken. - Arne (http://draketo.de) signature.asc Description: This is a digitally signed message part. -- Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Heya Arne, We're saddened at your unhappiness with the current direction, and glad that you have made a concrete effort at defining a suitable alternative semantics for special indentation extensions. Currently, however, the consensus seems to be "sweet-expressions will not switch directions, in any way, to use Arne's formulation." As discussed in the other thread, Proposal: ENLIST (Arne's ":"), http://www.mail-archive.com/readable-discuss@lists.sourceforge.net/msg01066.html , there are some issues which lead us to turn down your two interrelated proposals. Personally, I feel that your combined proposal can be made to work in a language that is restricted to operate in ASCII, or if you have an underlying implementation that reliably uses the same encoding as the programmer. With effort, it can be made to work even with double-width CJK characters and other Unicode nastiness. However, our goal is to develop a general notation that can be applicable across many Lisplike languages. Lisp is easy to implement - the original 'eval' definition was barely a page of text - and it's easy to parse for programs. Hence, the existence of many Lisps. Adding an indentation processor is already a tremendous complication in the parsing, but handling the full generality of Unicode would be an even worse complication (unless you restrict the important parts of the code, or even the entire code, to ASCII). Granted, your approach can be implemented using some sort of preprocessor separate from the core Lisp implementation; in fact, it seems to be defined so that this is easy (hence the need to denote single items with ".") and the preprocessor does not even need to actually understand Lisp syntax (meaning that potentially, a single preprocessor implementation can work with many Lisp implementations - the Lisp implementations just need to implement n-expressions, or even just curly-infix, both of which are far more trivial to add than indentation). This may be considered a point in its favor, although it certainly risks falling into the One True Implementation. We hope you continue to work with or on indentation-based syntaxes for Lisp, whether sweet-expressions, your current proposal, or some other future notation you can develop. Sincerely, AmkG -- Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_feb ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Alan Manuel Gloria: > I've been reviewing the ancient records (LOL was most of > sweet-expressions decided just last year? (^_^)v) > > So, this is just a recap of why the current sweet-expressions looks > the way it currently does. This is a nice (and humorous!) summary. Lots of in-jokes, so new readers may find this a challenge, but it is interesting to see the sequence. > As a complete and utterly gratuitous non-sequitur, I prefer (^.^) > smilies to :-) smilies because the () pair up in the former. A reasonable issue when discussing Lisps! It may be a regional thing too. David Crystal's "The Story of English in 100 Words", page 242, illustrates "cultural differences in the use of emoticons. In Western countries, emoticons are viewed sideways and focus on the mouth; in the East, they are horizontal and focus on the eyes". The table begins with this first entry: West East Smile:)^.^ > 1. David A. Wheeler started with indentation semantics in general > (i.e. deduce parens from indent) Actually, there was a "0": David searched for every effort ever done to make Lisps easier to read. > 4. List goes on hiatus as secondary participants move on, and David > (apparently) goes on a PhD-hunting spree and incidentally proves for > some reason that compiling things twice using open-source compilers > prevents some guy named ken from adding backdoors to every system on > the planet. I did include sweet-expressions (of the time) in my PhD dissertation, BTW. > 24. almkglor starts enjoying SUBLIST after finding that its limited, > simple semantics give surprisingly powerful expressive power. During > all this time, there are several tangential and not-so-tangential > discussions on the list, mostly about other Lisp-like languages. Although you tend to use SUBLIST more than I do, I completely agree, its simple semantics have surprising expressive power. In general, I want to have very few constructs, each of which are simple and powerful. My worry about adding an ENLIST at this point is that, unless there's a strong use case, I don't want to add MORE stuff. But let's look at a real proposal (as you've separately posted) and see where it goes. --- David A. Wheeler -- The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials, tech docs, whitepapers, evaluation guides, and opinion stories. Check out the most recent posts - join the conversation now. http://goparallel.sourceforge.net/ ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
I've been reviewing the ancient records (LOL was most of sweet-expressions decided just last year? (^_^)v) So, this is just a recap of why the current sweet-expressions looks the way it currently does. -- As a complete and utterly gratuitous non-sequitur, I prefer (^.^) smilies to :-) smilies because the () pair up in the former. -- The path that was tread by sweet-expressions to get to where we are now was basically: 1. David A. Wheeler started with indentation semantics in general (i.e. deduce parens from indent) 2. David then (apparently) searched through existing semi-formalized proposals for indentation and found SRFI-49: 2. a. Indentation means "child of next less indented line above it" 2. b. Multiple items on a line form a list 2. c. Single items are just that item. 2. d. Symbol 'group when found as the first item on a line is deleted (i.e. the magic non-existent symbol). To start a line with an actual "group" you double up the "group" so that the first group is deleted but the second remains (this is explained later on this list by Egil Moller; initially our understanding was that it forced a grouping). 3. David adds curly-infix and n-expressions over the basic SRFI-49 I-expressions (these two were somewhat independently built, mostly by David, although discussed in the list; in particular I think I (Alan) was the one who pointed out that automatic infix detection sucked, by using the "convoke" example). 4. List goes on hiatus as secondary participants move on, and David (apparently) goes on a PhD-hunting spree and incidentally proves for some reason that compiling things twice using open-source compilers prevents some guy named ken from adding backdoors to every system on the planet. 5. David begins planning out some extensions over the basic SRFI-49, describes them slightly on his webpage. Some posts exist on the list, scattered over 2006->2011, mostly David very occassionally posting something about something. 5. a. This includes some random stuff about "SPLICE", which is mostly due to Arc's nasty if syntax. Initially SPLICE is just a continuation marker, then David extends it so that it has an inline meaning (the same as the current GROUP/SPLIT when inline), and finally David extends it so that it becomes invisible when at the start of a line. SPLICE is spelled "\". 6. Arne floats the idea to replace "group" with the syntax ".". David mentions preferring a "larger" character ("because a period is almost too small") and floats the idea to use "\". This discussion peters out mostly unresolved. 7. Some guy named almkglor pops up late in June 2012, rants about how Haskell is kewl and how every Lisp should be exactly like Haskell except when it's like Lisp, and complains that every Haskell implementation he can find can't be bootstrapped on his employer's system except for Hugs98, which can't run GHC and doesn't have any of GHC's kewl extensions like type class families (which he still doesn't understand, but are kewl anyway). He builds a parser description for sweet-expressions using a system that exists only in his head. 8. almkglor incidentally mentions that "\" (which David last proposed as an alternative spelling for "group" instead of ".") was also proposed before by David as SPLICE. He points out that the SPLICE-at-the-end rule is not easily implementable on a one-char-lookahead machine, at least if you're going to consider whitespace+EOL == EOL (which you should). 9. Since David proposed "\" for SPLICE and later proposed "\" for GROUP, almkglor assumes that what David is actually proposing is that SPLICE and GROUP be somehow merged into a single semantic, and starts working out how to safely merge both. At this point GROUP is still considered as meaning "add an extra layer of indent" rather than the current meaning of "magical invisible symbol that is automatically removed if it's the very first symbol". 10. almkglor points out that Egil Moller himself said (in a message somewhere in the limbo of The Hiatus) that "group" was intended to be the magic invisible symbol, so that GROUP at the beginning was equivalent to not having anything there, it just marked a point at which that particular line actually indented. 11. almkglor points out that Egil Moller's explanation means that GROUP and SPLICE work exactly the same when at the start of a line. 12. almkglor and David start discussing GROUP, SPLICE, and another semantic called ENLIST (in modern terms, it acts more like the current ":" notation by Arne). Arne points out that SPLICE-inline rule is complicated to explain; almkglor counters with the fact that it's needed for easy usage of Arc if-syntax and CL keyword-syntax. 13. David trolls the mailing list with the idea to use "." for indentation. 14. almkglor goes on a spree of starting all sorts of threads on the mailinglist to confuse everyone else into submission. 15. almkglor renames SPLICE to SPLIT, since it's no longer actually a SPLICE, wit
Re: [Readable-discuss] unhappy with the current direction
Alan Manuel Gloria: > >> Your main contributions seem to be the extended "." behavior (. a => > >> a, . a b -> a b) and the ":" syntax. I don't see any use, even in > >> your examples, of the single-item-on-a-line-is-single-item-list > >> behavior. Arne Babenhauserheide: > > The reason for that is consistency: Making sure that when you learn a > > minimal set of rules you can understand the structure of all code you see. > Consistency and convenience are both needed in a notation. The key is > to find the balance between both. I completely agree, both are needed. I'll gladly cede that it's unlikely that any notation would please *everyone*, but that is a goal worth striving for. So let's look at the pros and cons of this idea, and if there are bad cons, if it's fixable or if pieces are ripe for stealing :-). > I think in this case, the > single-item case tends to occur more often than the > single-item-function-call case. Agree. Many Scheme procedures involve recursing down structures to eventually return some leaf or base cases, so single-items occur quite a bit at the leaves... and we want common cases to be easy to notate. In general, the common cases should be optimized and the hard cases possible. ... > So even if you insist on a separate preprocessing pass rather than a > full parser, it's possible to still correctly process the > single-item-line. > > There would be a simple way to fix it, though: Make the position of : only > > significant when you want to indent deeper. To make this consistent: Make > > the indentation of a line only relevant for deeper nested lines (child > > lines). Then the following would all be valid code: This semantic assumes there's something called a "column width" that you can measure for different characters, and that would be exactly the same for all systems. That once existed with fixed-width ASCII-only terminals, but increasingly that is simply not true. Alan mentioned CJK characters; there are also variable-width characters, varying fonts, and unsupported glyphs. Variable-width characters in particular bring this problem into sharp relief, even with ASCII. I think a notation that presumes that different character sequences have some equivalent "width" is broken. You can distinguish "beginning of line" from "not beginning of line", and after that, there's really nothing you can depend on. > >> ":" seems to put a lot of pressure on implementations, using your > >> current explanation. Perhaps we can change ":" to be more local (i.e. > >> it won't require keeping track of column position, and won't cause > >> cascading affects when text before it changes)? ... > >> How about this semantic instead? > >> > >> ":" introduces a (, and a promise to add ) at the end of that line. > > > > To make it more general, you can add that the ) is added before the first > > less or equally indented line, but that a later line can add a new > > indentation layer. This semantic for ":" makes lots more sense to me, since this avoids making the (false) assumption that we know anything about the widths of different character sequences. Let me call the older semantics magic-column-position semantics (because somehow you can magically figure out what a 'current' position is). Let me calls this newer semantic "line-ending" semantics, because the effect of ":" would end at the end of the line. > >> A new synthesis? > >> > >> Perhaps we can *keep* GROUP/SPLIT \\, SUBLIST $, and COLLECTINGLIST <* > >> *>, use the EXTENDPERIOD . a b, and add the new LINELIST : > > … > >> what you think? > > > > That would be the exact opposite of why I wrote. Instead of having 3 syntax > > elements, we now have 4 plus the . (which is just a generalization of (. > > a)). > > > > My intention was not to add more syntax overhead, but to reduce it by > > generalizing existing functionality. > > *shrug*. $ is not reducible to : - xref. above. Consider also that $ > is useful for other forms that could usefully get only one argument, > but that argument usually is a complex thingy. Such as: Agree, you can't use ":" to substitute for "$" or <*...*>. Especially if it just has the "insert ( here, and ) at the end of line" semantics. I do grant that I can see use cases for ":" defined with this limited semantic, and it's obviously easy to describe by itself. However, like Arne, I'm also concerned about adding ANOTHER syntactic construct. Especially because now you have to clearly explain how they work together (precedence returns!!). But for intellectual argument, let's continue the discussion; it may turn out to be worthwhile, or suggest something worthwhile. And if not, at least we can say we looked under that rock too :-). > To use it as a "$" replacement, you need to indent a *lot*. $ allows > reducing both horizontal and vertical space simultaneously; : requires > trading off one for the other. Either: > > call/cc : lambda (return) > blah ... return(42) blah .
Re: [Readable-discuss] unhappy with the current direction
Arne Babenhauserheide: > You might have noticed that after initial excitement I drew back from > readable again. The reasons were partly time problems, but mostly that I have > the feeling that readable currently moves into a direction which does not > feel right to me. I'm sorry to hear that. To be honest, I'm *delighted* with the current draft sweet-expression notation. But discussing this alternative now sounds like a good idea, as long as we don't get stuck in an endless "analysis paralysis". > There is now indentation based syntax (great!) with special casing for > sublists (useful for nested functions), restart lists (hm) and now <* ... *> > (looks alien). The latter two are the same thing. <*...*> is just the syntax for restart lists (now renamed to collection lists). > To me this lost the beauty of lisp, that you have few fixed syntax rules > which become second nature. Instead we now have mixed metaphors and code > which can be written in a multitude of ways - which goes counter to > readability (it’s not about every special case being beautiful, but having a > consistent style which is nicely readable in most cases). I definitely don't want to add an infinite amount of syntax, but the widespread rejection of Lisp shows that Lisp has gone too far on the "no syntax" extreme. Besides, anyone who says Scheme has no syntax has not tried to accurately parse Scheme numbers or identifiers :-). > And it just felt wrong to see more and more special cases being added. That > smelled of a problem in the basic concept. Sweet-expressions have a general rule, 3 special abbreviations for common circumstances ($, \\, and <*...*>), and neoteric-expressions. I don't think that's much at all. But a better approach, if it's actually better, is welcome. > Also I wondered how code like the following would be represented: > > (concat "I want " (getwish from me) " - " username) > > Currently I only see this option: > > concat "I want " getwish(from me) " - " username > > But not this > > concat "I want " >getwish from me >" - " username Well, you can of course do: ! concat "I want " ! ! getwish from me ! ! " - " ! ! username Or if you want to do it in 3 lines: ! concat "I want " ! ! getwish from me ! ! " - " \\ username So that's trivially handled in the current draft. > Essentially all it does is giving up the rule that a variable on its own is a > variable instead of a function call. That side-effect is unfortunate. Using f() as a function call is pretty clear, and returning "1" as a value is clear too. I fear this might lead to a lot lists being un-intentionally returned. IE, the rule may be simple, but it would lead to a lot of mistakes in practice. Having "f" on a line return f, and "f()" actually call f, is much clearer to me than ". f" to return f. It's especially odd if the return value is a number like "5". But let's discuss this alternative further... --- David A. Wheeler -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
On 2/11/13, Arne Babenhauserheide wrote: > Hi Alan, > > (I’m answering to both mails here) > > Am Montag, 11. Februar 2013, 11:07:30 schrieb Alan Manuel Gloria: >> Your main contributions seem to be the extended "." behavior (. a => >> a, . a b -> a b) and the ":" syntax. I don't see any use, even in >> your examples, of the single-item-on-a-line-is-single-item-list >> behavior. > > The reason for that is consistency: Making sure that when you learn a > minimal set of rules you can understand the structure of all code you see. > Consistency and convenience are both needed in a notation. The key is to find the balance between both. I think in this case, the single-item case tends to occur more often than the single-item-function-call case. Even for preprocessing, consider the following rule: A line is considered a "single-item line" if: 1. Strip trailing and leading spaces from the line. 2. If there are any spaces inside the line that are outside matched () [] {} "" #||#, it is not a single-item line. 3. Newlines/EOL inside matching () [] {} "" #||# are considered spaces and do not "terminate" the line. So even if you insist on a separate preprocessing pass rather than a full parser, it's possible to still correctly process the single-item-line. >> That's fine and all, but suppose I'm defining a method for Guile GOOPS? >> >> define-method : hack (x ) >> ! do-hack-on-cat x >> >> Oops, except hack only works on cats anyway, so I'll just optimize >> things (because profiling shows that method calls in GOOPS take up all >> my time, LOL) and turn hack into an ordinary function: >> >> define : hack x >> ! do-hack-on-cat x >> >> Oh, no!! Now I have to adjust the indentation of everything inside >> it! Luckily hack x just contains do-hack-on-cat, so all I need to do >> is adjust that single line. >> >> define : hack (x ) >> ! do-hack-on-cat x > > Well, I’m a Python-Programmer. In Python you run into that everytime you > remove or add an if. Before I used rectangle-edit, it disturbed me a bit. > Now it’s quite painless: > > C-SPACE M-↓ ↑ C-7 → C-x C-r C-k The example I show is worse, because it doesn't apply to just if: it applies to every misspelled token. Although > There would be a simple way to fix it, though: Make the position of : only > significant when you want to indent deeper. To make this consistent: Make > the indentation of a line only relevant for deeper nested lines (child > lines). Then the following would all be valid code: > > if : = a 1 >b > c > > if > = a 1 > b > c > > if : = a 1 > b > c > > if > = a 1 > b > c > > If the indentation is equal or lower than a previous indentation layer, the > bracket of that indentation layer gets closed. I see. This does lessen (but not remove) problem #1. > >> 3. You need to explicitly specify how double-width CJK characters are >> handled when found before a ":" (ban them in code? But what about >> strings and #| |# comments?). Do we treat them as single character >> columns (easy implementation, but potentially confusing, and possibly >> limiting international code) or do we treat them as double character >> columns (need to consider encoding, and implementations need to keep a >> list of all such double-width characters)? > > Being able to reduce indentation of later lines (as long as they stay child > lines) would also solve this for most cases. Please tell me: what should an implementation do when a double-width CJK character is encountered? Treat it as a +1 column position or +2 columns position? At the very least, say "+1 column position, so people should avoid using a : followed by a line more-indented than the : after a double-width character, as it would be confusing." Unless you're willing to pay the price of every implementation keeping a list of each double-width character. > >> ":" seems to put a lot of pressure on implementations, using your >> current explanation. Perhaps we can change ":" to be more local (i.e. >> it won't require keeping track of column position, and won't cause >> cascading affects when text before it changes)? > > For me the inline : mainly exists for consistency: It generalizes GROUP. > > Essentially GROUP adds a new indentation layer, so you could just allow > using it inline. But I use : for group, because I think that \\ looks alien > to normal text and so it hampers readability for all people who aren’t used > to bash-escaping. Our current semantic has settled on GROUP/SPLIT, not GROUP. So: ; Arc if cond1 \\ consequent 1 cond2 \\ consequent 2 \\ else-consequent 3 ==> (if cond1 (consequent 1) cond2 (consequent 2) (else-consequent 3)) The advantage of using GROUP/SPLIT rather than a separate GROUP and SPLIT is that \\ can be used to "spoof" such constructs as above. Basically, to "line up" the else-consequent together with its buddies in the Arc example. Compare the Scheme: ; Scheme cond cond1 $ consequent 1
Re: [Readable-discuss] unhappy with the current direction
Hi Alan, (I’m answering to both mails here) Am Montag, 11. Februar 2013, 11:07:30 schrieb Alan Manuel Gloria: > Your main contributions seem to be the extended "." behavior (. a => > a, . a b -> a b) and the ":" syntax. I don't see any use, even in > your examples, of the single-item-on-a-line-is-single-item-list > behavior. The reason for that is consistency: Making sure that when you learn a minimal set of rules you can understand the structure of all code you see. > That's fine and all, but suppose I'm defining a method for Guile GOOPS? > > define-method : hack (x ) > ! do-hack-on-cat x > > Oops, except hack only works on cats anyway, so I'll just optimize > things (because profiling shows that method calls in GOOPS take up all > my time, LOL) and turn hack into an ordinary function: > > define : hack x > ! do-hack-on-cat x > > Oh, no!! Now I have to adjust the indentation of everything inside > it! Luckily hack x just contains do-hack-on-cat, so all I need to do > is adjust that single line. > > define : hack (x ) > ! do-hack-on-cat x Well, I’m a Python-Programmer. In Python you run into that everytime you remove or add an if. Before I used rectangle-edit, it disturbed me a bit. Now it’s quite painless: C-SPACE M-↓ ↑ C-7 → C-x C-r C-k There would be a simple way to fix it, though: Make the position of : only significant when you want to indent deeper. To make this consistent: Make the indentation of a line only relevant for deeper nested lines (child lines). Then the following would all be valid code: if : = a 1 b c if = a 1 b c if : = a 1 b c if = a 1 b c If the indentation is equal or lower than a previous indentation layer, the bracket of that indentation layer gets closed. > 3. You need to explicitly specify how double-width CJK characters are > handled when found before a ":" (ban them in code? But what about > strings and #| |# comments?). Do we treat them as single character > columns (easy implementation, but potentially confusing, and possibly > limiting international code) or do we treat them as double character > columns (need to consider encoding, and implementations need to keep a > list of all such double-width characters)? Being able to reduce indentation of later lines (as long as they stay child lines) would also solve this for most cases. > ":" seems to put a lot of pressure on implementations, using your > current explanation. Perhaps we can change ":" to be more local (i.e. > it won't require keeping track of column position, and won't cause > cascading affects when text before it changes)? For me the inline : mainly exists for consistency: It generalizes GROUP. Essentially GROUP adds a new indentation layer, so you could just allow using it inline. But I use : for group, because I think that \\ looks alien to normal text and so it hampers readability for all people who aren’t used to bash-escaping. Inline : has nice features - if used sparingly - and I think it improves the readability of function definitions a lot. But if it were not necessary for double brackets, I would not propose adding it. Indentation based lisp syntax MUST support double brackets. That’s why : exists. Also it MUST support continuing the parameter list after a function call. That’s why . exists. Am Montag, 11. Februar 2013, 12:23:20 schrieb Alan Manuel Gloria: > 1. It seems that it currently doesn't handle ":" in the middle of a line, > yet. Jepp. It’s a quite limited late-night hack. It gives a draft how that parsing could work, but I did not get to implementing inline :. > 2. It seems that multiple ": " at the start of each line are ignored, > and only the last one is used. So the following is possibly (?) > valid: > > define foo(bar) > : cond > : : meow?(bar) > : : : cat bar > : : woof?(bar) > : : : dog bar > : : else > : : : error 'foo "error!" It’s not valid, since the “: cond” would start at the same indentation as the define, but the converter would process it. So this is a bug in the converter… > How about this semantic instead? > > ":" introduces a (, and a promise to add ) at the end of that line. To make it more general, you can add that the ) is added before the first less or equally indented line, but that a later line can add a new indentation layer. That would give the full behaviour (defining an indentation layer) while keeping the enhanced readability for deeply nested functions. > In the first place, ":" can't support the shown cond-pattern. So > without $, it would look like (without probe): > > define-stream stream-map(f s) > cond … > > With probe: > > define-stream stream-map(f s) > probe > cond … I think I see the merit of $ now: It wraps the rest of the code in a function call. > A new synthesis? > > Perhaps we can *keep* GROUP/SPLIT \\, SUBLIST $, and COLLECTINGLIST <* > *>, use the EXTENDPERIOD . a b, and add the new LINELIST : … > what you think? That would be
Re: [Readable-discuss] unhappy with the current direction
I looked at your python code: 1. It seems that it currently doesn't handle ":" in the middle of a line, yet. 2. It seems that multiple ": " at the start of each line are ignored, and only the last one is used. So the following is possibly (?) valid: define foo(bar) : cond : : meow?(bar) : : : cat bar : : woof?(bar) : : : dog bar : : else : : : error 'foo "error!" -- About ":" How about this semantic instead? ":" introduces a (, and a promise to add ) at the end of that line. It is like a limited $, except that $ will not wrap a single item on the line (: will) and $ can cross the line end. This localizes ":", meaning that we can use it this way: define : add-if-all-numbers lst call/cc lambda : exit let loop \\ lst lst sum 0 if : null? lst sum if : not : number? : car lst exit #f loop : cdr lst + sum : car lst This seems to be a lot more readable, since the previous rule for ":" *required* a lot more horizontal space; this time, it's optional (see the arguments to loop on the last two lines for a good use of it). -- When crossing line boundaries, $ does a better job than your current ":" idea, because it doesn't require keeping track of column positions. So I think $ should keep that job, and only use : for the limited case where it's useful to only put it to the end of the line. For example, say I'm debugging a long and boring stream function (using SRFI-41 streams). So I develop a "probe" function like so: define-stream probe(x) $ cond stream-pair?(x) $ begin display (stream-car x) \\ newline() stream-cons stream-car x probe $ stream-cdr x else$ stream-null And I apply it to my stream code like so: define-stream stream-map(f s) $ probe $ cond stream-pair?(x) $ stream-cons f $ stream-car x stream-map f $ stream-cdr x else$ stream-null In the first place, ":" can't support the shown cond-pattern. So without $, it would look like (without probe): define-stream stream-map(f s) cond stream-pair?(x) : stream-cons f : stream-car x stream-map f : stream-cdr x else: stream-null With probe: define-stream stream-map(f s) probe cond stream-pair?(x) : stream-cons f : stream-car x stream-map f : stream-cdr x else: stream-null So, just to probe my code, I need an extra indentation. With $, I don't need the extra indentation. ":" can't be used here (using your current idea for ":"), since it would require indenting even more than just using a separate line would. "$" is surprisingly versatile. - A new synthesis? Perhaps we can *keep* GROUP/SPLIT \\, SUBLIST $, and COLLECTINGLIST <* *>, use the EXTENDPERIOD . a b, and add the new LINELIST : Then we can do something like: <* define-library \\ (amkg foo) export . cat dog meow . whatever woof arf import (scheme base) <* begin define : cat x let : : y {x + 1} meow x y define : dog x woof $ meow {x - 1} {x + 2} ... *>;begin *>;define-library what you think? -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
On 2/11/13, Arne Babenhauserheide wrote: >> So: can you be more clear about how your indentation-based syntax >> interacts with the n-expression stack? > > That was a part I wasn’t perfectly sure about when I wrote - and which I > could not fix before sending, because I wrote late at night and knew that I > would not have time to improve it the next few days. > > Conceptually: > > - neoteric at the beginning of a line is hard to do right > (it would always be a double bracket). > - neoteric within a line, or in a line which starts with . > would just be the corresponding s-expression. > - curly-infix would just be the s-expression - except if > the whole line is curly-infix. I don’t like that exception… > maybe the line with only curly infix should just be prefixed > with a .. > > define : fibup maxnum count n-1 n-2 >if {maxnum = count} > . {n-1 + n-2} > fibup maxnum {count + 1} {n-1 + n-2} n-1 You know what I suggest? Drop the single-item-on-a-line-is-single-item-list rule. Include the "n-expression datum on a line by itself is just that item - if you want to code a function call to a 0-arity function, explicitly put () around or after" from sweet. None of your examples rely on the single-item-list behavior and must explicitly turn it off anyway, so I think you should optimize the presentation for the more common usage. Your main contributions seem to be the extended "." behavior (. a => a, . a b -> a b) and the ":" syntax. I don't see any use, even in your examples, of the single-item-on-a-line-is-single-item-list behavior. > > > > The : is just a shortcut for starting a new line at the indentation of the > :. So > >define : fibfast n > if {n < 2} > . n > fibup n 2 1 0 > > could be written as > >define > fibfast n > if {n < 2} > . n > fibup n 2 1 0 That's fine and all, but suppose I'm defining a method for Guile GOOPS? define-method : hack (x ) ! do-hack-on-cat x Oops, except hack only works on cats anyway, so I'll just optimize things (because profiling shows that method calls in GOOPS take up all my time, LOL) and turn hack into an ordinary function: define : hack x ! do-hack-on-cat x Oh, no!! Now I have to adjust the indentation of everything inside it! Luckily hack x just contains do-hack-on-cat, so all I need to do is adjust that single line. define : hack (x ) ! do-hack-on-cat x -- The advantage of the current approach is that column positions are only significant for the first non-whitespace non-! character on a line. : breaks that. It now makes :'s column position significant. This has some drabacks 1. As seen above, changing text before the ":" marker will potentially affect the interpretation of every non-blank line after that. This is in contrast to \\ and $, which are completely localized. Sure, it's rare to change define-method (or define-whatever) to define, but suppose I had misspelled defin-method and started continuously coding several lines? What if I misspelled one of my own non-standard macros (so that the IDE won't highlight it, since it doesn't recognize the the correctly spelled keyword anyway, meaning a very high chance of me missing any misspelling)? 2. The implementation now needs to keep track of column positions all the time, because we are never sure that we won't encounter it suddenly. This is significant because it means a complete reimplementation of n-expressions, one that does indeed keep track of column positions. This means we also need to completely reimplement string parsing (currently we depend on the underlying Lisp's implementation), symbol parsing, and number parsing. 3. You need to explicitly specify how double-width CJK characters are handled when found before a ":" (ban them in code? But what about strings and #| |# comments?). Do we treat them as single character columns (easy implementation, but potentially confusing, and possibly limiting international code) or do we treat them as double character columns (need to consider encoding, and implementations need to keep a list of all such double-width characters)? ":" seems to put a lot of pressure on implementations, using your current explanation. Perhaps we can change ":" to be more local (i.e. it won't require keeping track of column position, and won't cause cascading affects when text before it changes)? -- In conclusion: I think the extended "." is OK, ":" not so much (needs more explaining/thinking). I object to the single-entity-is-list-of-one-item rule. Sincerely, AmkG -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ Readable-discuss mailing list Readable-
Re: [Readable-discuss] unhappy with the current direction
Hi Alan, Thank you for your answer! Am Samstag, 9. Februar 2013, 13:43:23 schrieb Alan Manuel Gloria: > On Sat, Feb 9, 2013 at 7:47 AM, Arne Babenhauserheide wrote: > > By prefixing all variables with “.”, it also gets line continuations for > > free: > > > > a b c d e > > . f g h > > . i j k > > > > is equivalent to > > > > (a b c d e > >f g h > >i j k) > > > > Really? Because your rule is: > > > - if it is indented equally, then it closes a bracket and opens a new one > > (except if it starts with a ., then it only closes a bracket). > > So: > (a b c d e > f g h > ) i j k Ouch, yes you’re right - good catch! > ... or something anyway. Maybe "." should raise a flag that > suppresses ")" for the next line. But I think that ends up having a > stack in the case of indentation. > > ...or something, at least. Hehe. Essentially a line starting with . should always continue the previous less-indented line. So the example is what I envision, but my rules do not work for double usage of it. Best wishes, Arne -- 1w6 sie zu achten, sie alle zu finden, in Spiele zu leiten und sacht zu verbinden. → http://1w6.org signature.asc Description: This is a digitally signed message part. -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Am Sonntag, 10. Februar 2013, 21:22:23 schrieb Alan Manuel Gloria: > Okay, I checked, and I'm not sure how you propose to handle curly-infix. > > It seems, according to your examples, that a line composed of a single > curly-infix item is that item, not a list of that item. I rather see curly infix as rewriting the expression: {n-1 + n-2} to + n-1 n-2 but that only works at the beginning of a line. Deeper in the line, it has to become the corresponding s-expression… > So: can you be more clear about how your indentation-based syntax > interacts with the n-expression stack? That was a part I wasn’t perfectly sure about when I wrote - and which I could not fix before sending, because I wrote late at night and knew that I would not have time to improve it the next few days. Conceptually: - neoteric at the beginning of a line is hard to do right (it would always be a double bracket). - neoteric within a line, or in a line which starts with . would just be the corresponding s-expression. - curly-infix would just be the s-expression - except if the whole line is curly-infix. I don’t like that exception… maybe the line with only curly infix should just be prefixed with a .. define : fibup maxnum count n-1 n-2 if {maxnum = count} . {n-1 + n-2} fibup maxnum {count + 1} {n-1 + n-2} n-1 The : is just a shortcut for starting a new line at the indentation of the :. So define : fibfast n if {n < 2} . n fibup n 2 1 0 could be written as define fibfast n if {n < 2} . n fibup n 2 1 0 And : . does not change the meaning of the code: a b : . c d is the same as a b c d but it sets an indentation level, so in the following, the second line would have higher indentation than a dotted line: a b : . c d is the same as a b . c d which would be dangerous, because the . actually reduces the indentation of the line by one and d gets a doubled indentation which is not marked and would be quite confusing. Best wishes, Arne -- Ein Würfel System - einfach saubere Regeln: - http://1w6.org signature.asc Description: This is a digitally signed message part. -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Am Sonntag, 10. Februar 2013, 20:48:29 schrieb Alan Manuel Gloria: > Attached find a simple implementation (which does *not* handle > comments, blank lines, and ":"). Wow, that’s cool! The only parsing issue I spotted right away is that it appends a final opening bracket. I tried writing a python-based preprocessor, but that one uses multiple phases for preprocessing, since I always fumbled when I tried to wrap my mind around parsing indentation without aid… Best wishes, Arne -- 1w6 sie zu achten, sie alle zu finden, in Spiele zu leiten und sacht zu verbinden. → http://1w6.org #!/usr/bin/env python3 class Line: def __init__(self, line): self.continues = line.lstrip().startswith(". ") if self.continues: self.content = line.lstrip()[2:].lstrip() else: self.content = line.lstrip() self.indent = len(line) - len(line.lstrip()) while self.content.startswith(": ") and self.content[2:].lstrip(): self.indent += len(self.content) - len(self.content[2:].lstrip()) self.content = self.content[2:].lstrip() if self.content.strip() == ":": self.content = "" def wisp2lisp(code): """Turn wisp code to lisp code.""" # first get rid of linebreaks in strings instring = False nostringbreaks = [] for char in code: if char == '"': instring = not instring if instring and char == "\n": nostringbreaks.append("\\n") else: nostringbreaks.append(char) code = "".join(nostringbreaks) # now read the indentation lines = [] for line in code.splitlines(): lines.append(Line(line)) # finally emit matching lisp code # write into the lisp lines with a delay of 1 line lisplines = [] levels = [] prev = lines[0] if not prev.continues: prev.content = "(" + prev.content for line in lines[1:]: # continuing lines do not get a leading bracket. if not line.continues: line.content = "(" + line.content # rising indent: sibling function or variable if line.indent > prev.indent: levels.append(line.indent) lisplines.append(prev.indent * " " + prev.content) # same indent: neighbour function of variable: close the previour lines bracket if line.indent == prev.indent: lisplines.append(prev.indent * " " + prev.content + ")") # lower indent: parent funtion or variable. Find the number of brackets to close if prev.indent > line.indent: bracketstoclose = len([level for level in levels if level >= line.indent]) levels = levels[:-bracketstoclose + 1] if prev.continues: bracketstoclose -= 1 lisplines.append(prev.indent * " " + prev.content + ")" * bracketstoclose) prev = line lisplines.append(prev.indent * " " + prev.content + ")" * (len(levels))) return "\n".join(lisplines) if __name__ == "__main__": print() with open("example.w") as f: wisp = f.read() print(wisp2lisp(wisp)) signature.asc Description: This is a digitally signed message part. -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Okay, I checked, and I'm not sure how you propose to handle curly-infix. It seems, according to your examples, that a line composed of a single curly-infix item is that item, not a list of that item. In fact, I think I want to be very clear on what, exactly, it is that you envision the following code to be in s-expressions: define : fibup maxnum count n-1 n-2 if {maxnum = count} {n-1 + n-2} fibup maxnum {count + 1} {n-1 + n-2} n-1 >From this example, it appears that there's special handling for curly-infix, because using the set of rules I derived from what I think is the intent of your ruleset (and hand-processing ":"), this becomes: (define (fibup maxnum count n-1 n-2) (if (= maxnum count) ((+ n-1 n-2)) ; huh?? (fibup maxnum (+ count 1) (+ n-1 n-2) n-1))) In fact, I think I want to be much more clear here: So: can you be more clear about how your indentation-based syntax interacts with the n-expression stack? Sincerely, AmkG -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
Attached find a simple implementation (which does *not* handle comments, blank lines, and ":"). I've also pushed it on the git repo. On Sat, Feb 9, 2013 at 4:59 PM, Alan Manuel Gloria wrote: > On Sat, Feb 9, 2013 at 1:43 PM, Alan Manuel Gloria wrote: >> - at the start of the read, the "previous line's indent" is considered >> as negative. >> - A line with the same indent as the previous line inserts a ")". It >> also inserts a "(" unless the line starts with "." >> - a line with a greater indent than the previous line inserts a "(" >> unless the line starts with "." >> - a line with a lesser indent than the previous line inserts a ")" for >> each indentation level popped, followed by a closing ")" >> - "." at the start of the line is removed. >> > > Scratch that. Here's a better implementation, based on what I see as > the core stuff you want. > > This ruleset bans a more indented line after a "."-initial line. None > of your examples shows that case, and I think that the simplistic > approach I'm using is hard to hack a decent effect with it. I also > ignore ":", because I'm not sure if its effect crosses line boundaries > (and if it does, how you're supposed to handle double-width CJK > characters.) > > - the reader has two variables: a stack of indentation levels, and a > boolean dot flag. Initially the stack contains a single negative > item, and the dot flag is false. > - When the current line is more indented than the stack top: > - - if the dot flag is set, error!! > - - if it starts with ".", just set the dot flag > - - otherwise insert a "(" and clear the dot flag and push the new > indent on the stack. > - When the current line is at the same indent as the stack top: > - - if the dot flag is cleared, insert ")". > - - if it starts with ".", just set the dot flag > - - otherwise insert a "(" and clear the dot flag > - Otherwise: > - - if the dot flag is cleared, insert ")" > - - pop off stack items until we reach an indent with the exact same > indent as the current line; emit ")" for each popped item (warning: > off-by-one error might be here, so need to actually check by > implementing) > - - if it starts with "." just set the dot flag > - - otherwise insert a "(" and clear the dot flag > > nb: blank lines might cause (), need to consider those. > nb: also, see the warning above, need to actually check it. > > Hope this helps. If you can get an implementation (even just a simple > one that does a text-to-text substitution, and without ":", like the > above) show us so we can think about it more. > > Sincerely, > AmkG arne-formulation.scm Description: Binary data sample.arne Description: Binary data -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
On Sat, Feb 9, 2013 at 1:43 PM, Alan Manuel Gloria wrote: > - at the start of the read, the "previous line's indent" is considered > as negative. > - A line with the same indent as the previous line inserts a ")". It > also inserts a "(" unless the line starts with "." > - a line with a greater indent than the previous line inserts a "(" > unless the line starts with "." > - a line with a lesser indent than the previous line inserts a ")" for > each indentation level popped, followed by a closing ")" > - "." at the start of the line is removed. > Scratch that. Here's a better implementation, based on what I see as the core stuff you want. This ruleset bans a more indented line after a "."-initial line. None of your examples shows that case, and I think that the simplistic approach I'm using is hard to hack a decent effect with it. I also ignore ":", because I'm not sure if its effect crosses line boundaries (and if it does, how you're supposed to handle double-width CJK characters.) - the reader has two variables: a stack of indentation levels, and a boolean dot flag. Initially the stack contains a single negative item, and the dot flag is false. - When the current line is more indented than the stack top: - - if the dot flag is set, error!! - - if it starts with ".", just set the dot flag - - otherwise insert a "(" and clear the dot flag and push the new indent on the stack. - When the current line is at the same indent as the stack top: - - if the dot flag is cleared, insert ")". - - if it starts with ".", just set the dot flag - - otherwise insert a "(" and clear the dot flag - Otherwise: - - if the dot flag is cleared, insert ")" - - pop off stack items until we reach an indent with the exact same indent as the current line; emit ")" for each popped item (warning: off-by-one error might be here, so need to actually check by implementing) - - if it starts with "." just set the dot flag - - otherwise insert a "(" and clear the dot flag nb: blank lines might cause (), need to consider those. nb: also, see the warning above, need to actually check it. Hope this helps. If you can get an implementation (even just a simple one that does a text-to-text substitution, and without ":", like the above) show us so we can think about it more. Sincerely, AmkG -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ Readable-discuss mailing list Readable-discuss@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/readable-discuss
Re: [Readable-discuss] unhappy with the current direction
On Sat, Feb 9, 2013 at 7:47 AM, Arne Babenhauserheide wrote: > Hi, > > You might have noticed that after initial excitement I drew back from > readable again. The reasons were partly time problems, but mostly that I have > the feeling that readable currently moves into a direction which does not > feel right to me. > > There is now indentation based syntax (great!) with special casing for > sublists (useful for nested functions), restart lists (hm) and now <* ... *> > (looks alien). > > > To me this lost the beauty of lisp, that you have few fixed syntax rules > which become second nature. Instead we now have mixed metaphors and code > which can be written in a multitude of ways - which goes counter to > readability (it’s not about every special case being beautiful, but having a > consistent style which is nicely readable in most cases). > > > And it just felt wrong to see more and more special cases being added. That > smelled of a problem in the basic concept. > > > Also I wondered how code like the following would be represented: > > (concat "I want " (getwish from me) " - " username) > > Currently I only see this option: > > concat "I want " getwish(from me) " - " username > > But not this > > concat "I want " >getwish from me >" - " username > > > I did not get my mind off the idea, though (and did not want to), and I > derived a simpler concept from it: > > - if a line starts with a . it is a continuation of the parent line > (the last line which had lower indentation). > - if a line is further indented than the previous line, > it opens a new bracket (except if it starts with a .), > - if it is indented equally, then it closes a bracket and opens a new one > (except if it starts with a ., then it only closes a bracket). > - A : sourrounded by whitespace defines a new indentation level > (similar to restart list, but more general). > > That provides 4 clear rules, one of which is similar to an existing rule > ( “(. a) → a” becomes “(. a b c) → a b c” ). And that’s all the syntax to > learn with no special cases. > > > Essentially all it does is giving up the rule that a variable on its own is a > variable instead of a function call. > > > By prefixing all variables with “.”, it also gets line continuations for free: > > a b c d e > . f g h > . i j k > > is equivalent to > > (a b c d e >f g h >i j k) > Really? Because your rule is: > - if it is indented equally, then it closes a bracket and opens a new one > (except if it starts with a ., then it only closes a bracket). So: (a b c d e f g h ) i j k ? > > And the problematic code switches to > > > concat "I want " >getwish from me >. " - " username You know, this second example suggests that maybe the "then it only closes the bracket" is incorrect. Here's a set that seems to be closer to what you want (ignoring ":" for now) - at the start of the read, the "previous line's indent" is considered as negative. - A line with the same indent as the previous line inserts a ")". It also inserts a "(" unless the line starts with "." - a line with a greater indent than the previous line inserts a "(" unless the line starts with "." - a line with a lesser indent than the previous line inserts a ")" for each indentation level popped, followed by a closing ")" - "." at the start of the line is removed. So: concat "I want" getwish from me . " - " username at the start of read, the previous line's indent is negative, so "concat" at indent 0 is more indented and inserts a "(": (concat "I want" ^ getwish from me . " - " username the next line is more indented than the previous line, so insert: (concat "I want" (getwish from me ^ . " - " username The next line has same indent, but also a ".", so insert only a ")": (concat "I want" (getwish from me ) " - " username ^ The next line is empty, which is an indent at 0, so pop off one indent (one ")") and add a closing ): (concat "I want" (getwish from me ) " - " username )) erk, that has an extra ")", ... or something anyway. Maybe "." should raise a flag that suppresses ")" for the next line. But I think that ends up having a stack in the case of indentation. ...or something, at least. Hehe. > > > Some of the Examples¹ from the sf.net site look like this (also using curly > infix, since that’s useful for easier math): > > >define : fibfast n > if {n < 2} > . n > fibup n 2 1 0 > > define : fibup maxnum count n-1 n-2 >if {maxnum = count} > {n-1 + n-2} > fibup maxnum {count + 1} {n-1 + n-2} n-1 > > define : factorial n >if {n <= 1} >. 1 >{n * factorial{n - 1}} > > define : gcd x y >if {y = 0} >. x >gcd y : rem x y > > > > define : add-if-all-numbers lst >call/cc > la