Re: [racket-users] Question about style

2018-08-17 Thread Hendrik Boom
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

2018-08-16 Thread Neil Van Dyke

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

2018-08-16 Thread Philip McGrath
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

2018-08-16 Thread Greg Hendershott
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

2018-08-16 Thread Deren Dohoda
>
> 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

2018-08-16 Thread Robert Girault
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

2018-08-16 Thread Bob Heffernan
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

2018-08-16 Thread Matthias Felleisen


> 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

2018-08-16 Thread Robert Girault
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

2018-08-16 Thread 'Paulo Matos' via Racket Users



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

2018-08-12 Thread Greg Hendershott
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

2018-08-11 Thread Deren Dohoda
>
>
>
> 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

2018-08-11 Thread Bob Heffernan
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.