Re: [racket-users] Question about style
On Thu, Aug 16, 2018 at 07:25:42PM -0400, Deren Dohoda wrote: > > > > Thanks for the up-vote but let me explain the “local” rationale here and > > vote for the ‘inner define’ variant. > > [snip]... > > > > > > In Racket programs for the world, possibly real, you want to avoid > > rightward drift. Indenting deeper and deeper makes code appear ‘ugly’ to > > many eyes, especially those used to other languages. But I will say this is > > also the one point about ‘ugly’-syntax languages that I have learned to > > appreciate (plus some concision in names). > > > > Internal defines are thus much more preferable than local, let, letrec, > > and similar constructs. See the Style Guide, where I spelled this out in a > > bit more detail. > > > > In general cases I agree with this and view heavy indenting as at a minimum > code smell but 'let' is so conceptually simple to work with syntactically. In a Lisp-like language I once introduced a syntactic extension: ( a b c / d e f / g h i) would always be equivalent to (a b c ( d e f ( g h i))) In cases where I would normally tail-nest, this reduced everything to syntactically non-nested parentheses. / worked a lot like a semicolon in conventional languages, but I tended to place it near the beginning of the line: ( a b c / d e f / g h i ) This was very readable, and did a lot to make Lisp pleasant. Unfortuntely, there aren't many leftover special characters in Scheme that can be used for this. I had not defined / to mean division. > If I want to extend/alter/make an analogous construction of 'let' it's > three to twenty lines depending on what I'm doing. I have no clue how to > start messing with internal definitions in a similar way. My 'let' construction was simple a three-argument ( let a b c) Iterated for a nonrecursive sequence of lets ( let a b / let c d / if c foo / if d bar whateverelse ) And this fit nicely with an if-then-else chain as well -- hendrik > > Deren > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
Bob Heffernan wrote on 08/16/2018 12:43 PM: When it comes to nesting (which, I guess, means the use of let) vs internal defines: is this purely an aesthetic thing? I think, practically, you could call it only aesthetic, since the PLT developers are invested in making internal `define` work as well as `let`. Early in the evolution of Racket, it was PLT Scheme. Early on, one could often see instantly that a bit of code was written by a PLT person, because only Matthias and his students (many now professors) would do things like use square brackets. One way to look at things like square brackets and internal `define` are like a charming accent on a language that you also speak. And maybe yours is a charming accent, to them. An accent doesn't have to be a big barrier to communication; your ear quickly learns to adapt. And, most importantly, an accent tends to come along with a very valuable diversity of ideas. In the case of seeing PLT Scheme from the outside, some of us could see some other value separate from the accent, and we decided to go live in PortLanTia. (I can hear the groans even before I click Send.) Many of us in PortLanTia have our own unique and evolving accents. I think that's a good thing, helping to keep the collective intellectually fresh and open, and not get too insular. You can speak however you like in PortLanTia. "https://docs.racket-lang.org/style/"; is only the style guide for official government (i.e., Git commits to code of core Racket itself). The newspapers, novelists, and businesses have their own styles, and the government doesn't dictate how they speak. Now, if you're new to the language of PortLanTia, and you don't yet know what your accent will be, you might start by trying to speak according to the style of the official government documents. It's conveniently written up, you don't yet know how the important subtleties differ from things you already know from elsewhere, and this style was prescribed by those who knew some of the subtleties well. Over time, as you know more, your own style will emerge, influenced by your background, linguistic style that you happened to think about, experiment with, etc. PortLanTia also happens to be extremely supportive of linguistic extension and research/experimenting. This is not irreconcilable with more prescription for a given purpose, such as style conventions for the code of core Racket. In engineering and elsewhere, we often make practical decisions with complex tradeoffs that we know we can't fully measure or understand, and one thing we tend to do is to limit the scope. Limiting scope lets us make a decision about fuzzy balances for one class of situations, without the difficulty, costs, and risks of making it for a much larger set of situations. And we very often get spreading influence behavior outside the scope for that decision, including a decision for a different scope explicitly referencing or delegating to that other decision, with or without modification. But there's no overwhelming pressure to defer to precedent, and PortLanTia's effort into `#lang` and other features are practically begging you to also try numerous very different things than the founders could foresee. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
With just a few more parentheses, I have a macro that lets you write: (def [x 0] [y 1] [z 2] ;; or even [(f x) (/ (+ x y) z)]) http://docs.racket-lang.org/adjutor/Stable.html#(form._((lib._adjutor%2Fmain..rkt)._def)) I like explicit delimiters, but I agree that a bunch of one-line `define`s feels pretty painful. -Philip On Fri, Aug 17, 2018 at 3:21 AM, Greg Hendershott wrote: > Have you ever considered extending the grammar of define from this: > > (define id expr) > (define (head args) body ...+) > > To this: > > (define id expr ... ...); <-- like e.g. `hash` > (define (head args) body ...+) > > So we could write things like: > > (define x 0 > y 1 > z 2) > > Sometimes so much writing/reading of "define" feels like too low a > signal:noise ratio. > > Or would this cause problems? > > > p.s. I guess it's a slippery slope. For instance what I'd like even > more is for `match-define` extended that way, and given a name like > `define` or `def`: > > (define pat expr ... ...) > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
Have you ever considered extending the grammar of define from this: (define id expr) (define (head args) body ...+) To this: (define id expr ... ...); <-- like e.g. `hash` (define (head args) body ...+) So we could write things like: (define x 0 y 1 z 2) Sometimes so much writing/reading of "define" feels like too low a signal:noise ratio. Or would this cause problems? p.s. I guess it's a slippery slope. For instance what I'd like even more is for `match-define` extended that way, and given a name like `define` or `def`: (define pat expr ... ...) -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
> > Thanks for the up-vote but let me explain the “local” rationale here and > vote for the ‘inner define’ variant. > [snip]... > > > In Racket programs for the world, possibly real, you want to avoid > rightward drift. Indenting deeper and deeper makes code appear ‘ugly’ to > many eyes, especially those used to other languages. But I will say this is > also the one point about ‘ugly’-syntax languages that I have learned to > appreciate (plus some concision in names). > > Internal defines are thus much more preferable than local, let, letrec, > and similar constructs. See the Style Guide, where I spelled this out in a > bit more detail. > In general cases I agree with this and view heavy indenting as at a minimum code smell but 'let' is so conceptually simple to work with syntactically. If I want to extend/alter/make an analogous construction of 'let' it's three to twenty lines depending on what I'm doing. I have no clue how to start messing with internal definitions in a similar way. Deren -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
On Thu, Aug 16, 2018 at 10:25 AM Matthias Felleisen wrote: > > On Aug 16, 2018, at 8:22 AM, Robert Girault > > wrote: > > > > I think I'd write your example like this. > > > > (define (foo x) > > (local ((define y (f x)) > > (define z (g y)) > > (define p (h z))) > >(bar p))) > > > > (If I knew what f, g, h do, I might write it differently. If they're > > all only for computing p, local expresses the fact.) > > > > I was educated by HtDP 1st edition: > > > > https://htdp.org/2018-01-06/Book/part_three.html#%28part._sec~3alocal-definitions%29 > > Thanks for the up-vote but let me explain the “local” rationale here and vote > for the ‘inner define’ variant. [...] > Style Guide https://docs.racket-lang.org/style/index.html Nice to know. Thank you. (I'll keep it ``in my backpack.'') -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
On 18-08-16 11:43, 'Paulo Matos' via Racket Users wrote: > I really, really don't like nesting and a few years ago adopted the > style of internal defines. It makes for much more readable code: > > (define (foo x) > (define y (f x)) > (define z (g y)) > (define p (h z)) > > (bar p)) Thank you to Paulo and everybody else for your very helpful feedback. When it comes to nesting (which, I guess, means the use of let) vs internal defines: is this purely an aesthetic thing? Regards, Bob -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
> On Aug 16, 2018, at 8:22 AM, Robert Girault > wrote: > > I think I'd write your example like this. > > (define (foo x) > (local ((define y (f x)) > (define z (g y)) > (define p (h z))) >(bar p))) > > (If I knew what f, g, h do, I might write it differently. If they're > all only for computing p, local expresses the fact.) > > I was educated by HtDP 1st edition: > > https://htdp.org/2018-01-06/Book/part_three.html#%28part._sec~3alocal-definitions%29 Thanks for the up-vote but let me explain the “local” rationale here and vote for the ‘inner define’ variant. I added ‘local’ to the TEACHING languages for semantic consistency. This decision was based on my inner semanticist rather than mass psychology of students but with psychology in mind. 1. A series of global (in the sense of 'module level') defines have a certain semantics (both static and dynamic). If you experiment using global defines and then move them into the innards of a function, you want the _exact_ _same_ semantics. So (define a (A 0)) (define b (B 1)) (define c (C 2)) would become (define (f x) (define a (A 0)) (define b (B 1)) (define c (C 2)) . . . ) This works well and fine for many but _not all_ sequences. For some you got a different error message .. and I consider rare but feasible failure in a teaching setting _insidious_. So I decided to come up with a construct that preserves the exact same semantics. 2. There is a secondary but minor reason. Internal defines introduce a new syntactic category into the language while ‘local’ defines simply extend the syntactic category of expressions. I like keeping the number of syntactic categories small. And I was afraid that once I opened the door, we’d get many things. 3. Since I made this decision, we also changed Racket’s behavior so that it signals undefined defines (during evaluation) uniformly. For all I know the semantic rationale (pt. 1) no longer applies, only the syntactic one (pt. 2). 4. While the teaching languages share syntax with Racket (as in #lang racket), they are not Racket. ;; - - - In Racket programs for the world, possibly real, you want to avoid rightward drift. Indenting deeper and deeper makes code appear ‘ugly’ to many eyes, especially those used to other languages. But I will say this is also the one point about ‘ugly’-syntax languages that I have learned to appreciate (plus some concision in names). Internal defines are thus much more preferable than local, let, letrec, and similar constructs. See the Style Guide, where I spelled this out in a bit more detail. — Matthias Style Guide https://docs.racket-lang.org/style/index.html -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
On Thu, Aug 16, 2018 at 6:44 AM 'Paulo Matos' via Racket Users wrote: > On 11/08/18 16:11, Bob Heffernan wrote: > > Dear all, > > > > I am new to Racket and only slightly less new to scheme & scheme-like > > languages. > > > > I have noticed myself often doing something like the following: > > > > (define (foo x) > > (let* ([y (f x)] > > [z (g y)] > > [p (h z)]) > > (bar p))) > > I really, really don't like nesting and a few years ago adopted the > style of internal defines. It makes for much more readable code: > > (define (foo x) > (define y (f x)) > (define z (g y)) > (define p (h z)) > > (bar p)) > > I avoid nesting, long lines and short names. So I would try to name the > variables appropriatelly. If intermediate variables don't have a > 'meaning' such that they can be given proper names, maybe they don't > deserve to be a variable and instead I will compose. I think I'd write your example like this. (define (foo x) (local ((define y (f x)) (define z (g y)) (define p (h z))) (bar p))) (If I knew what f, g, h do, I might write it differently. If they're all only for computing p, local expresses the fact.) I was educated by HtDP 1st edition: https://htdp.org/2018-01-06/Book/part_three.html#%28part._sec~3alocal-definitions%29 -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
On 11/08/18 16:11, Bob Heffernan wrote: > Dear all, > > I am new to Racket and only slightly less new to scheme & scheme-like > languages. > > I have noticed myself often doing something like the following: > > (define (foo x) > (let* ([y (f x)] > [z (g y)] > [p (h z)]) > (bar p))) I really, really don't like nesting and a few years ago adopted the style of internal defines. It makes for much more readable code: (define (foo x) (define y (f x)) (define z (g y)) (define p (h z)) (bar p)) I avoid nesting, long lines and short names. So I would try to name the variables appropriatelly. If intermediate variables don't have a 'meaning' such that they can be given proper names, maybe they don't deserve to be a variable and instead I will compose. Just my 2 cents. Paulo Matos > > Which could, of course, be written as > > (define (foo x) > (bar (h (g (f x) > > Here's an example from something I was just working on: > > (define (get-data input) > (let* ([url-string (construct-url input)] > [url (string->url url-string)] > [port (get-pure-port url)]) > (read-json port))) > > which, again, could be written as: > (define (get-data input) > (read-json (get-pure-port (string->url (construct-url input) > > My question is: is the way I'm writing things considered to be bad > style? It feels like a hangover from more imperative-style programming > & the inclination to do one thing "per line". On the other hand, it > often helps readability. > > It might be, of course, that both versions amount to the same thing > after the interpreter has been at them. > > Thanks and regards, > Bob Heffernan > -- Paulo Matos -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
As others said, naming intermediate values can make things clearer. (Taken too far, maybe it's hard to see the forest for the trees? I think it depends on the audience and the domain.) You happened to choose an example that illustrates a reason maybe not to do this with let* or define -- cleaning up resources like input ports. I would write this particular thing using call/input-url. https://docs.racket-lang.org/net/url.html#(def._((lib._net%2Furl..rkt)._call%2Finput-url)) For instance, I'd probably change construct-url to return a url struct like its name suggests, then write something like: (define (get-data input) (define url (construct-url input)) (call/input-url url get-pure-port read-json)) or perhaps just: (define (get-data input) (call/input-url (construct-url input) get-pure-port read-json)) This takes care of closing the port, even if read-json errors. Also, I like the way it reads: "From this URL, connect this way, and read this way." So, this is another way to name pieces, taking advantage of well-chosen names for the functions. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] Question about style
> > > > My question is: is the way I'm writing things considered to be bad > style? It feels like a hangover from more imperative-style programming > & the inclination to do one thing "per line". On the other hand, it > often helps readability. > I invariably write my code like this. I just think it's easier to understand two years later. I have a few let-like macros for this reason. 1) print-let /print-let*, for printf-debugging of let forms. 2) andlet / andlet*, for stopping binding evaluation in a let when the value to bind is #f (then the whole 'let' expression is #f). Sometimes I use internal 'define's instead, based on feel for heavily-indented code. I rarely try to write a complicated expression directly without some kind of explanatory setup. I have tinkered with some other 'let'-like forms but these two in particular are really useful. Deren -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[racket-users] Question about style
Dear all, I am new to Racket and only slightly less new to scheme & scheme-like languages. I have noticed myself often doing something like the following: (define (foo x) (let* ([y (f x)] [z (g y)] [p (h z)]) (bar p))) Which could, of course, be written as (define (foo x) (bar (h (g (f x) Here's an example from something I was just working on: (define (get-data input) (let* ([url-string (construct-url input)] [url (string->url url-string)] [port (get-pure-port url)]) (read-json port))) which, again, could be written as: (define (get-data input) (read-json (get-pure-port (string->url (construct-url input) My question is: is the way I'm writing things considered to be bad style? It feels like a hangover from more imperative-style programming & the inclination to do one thing "per line". On the other hand, it often helps readability. It might be, of course, that both versions amount to the same thing after the interpreter has been at them. Thanks and regards, Bob Heffernan -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.