Re: [racket-users] Racket7 Conceit

2017-07-19 Thread Ben Greenman
mflatt answered some "why"s on the racket-dev list:
https://groups.google.com/d/msg/racket-dev/2BV3ElyfF8Y/4RSd3XbECAAJ

On Thu, Jul 20, 2017 at 12:34 AM, Lehi Toskin  wrote:

> I've read through a few README's in the racket7 repo and I can't find
> anything specifically about *why* Racket is being implemented on top of
> Chez Scheme, so I suppose I'll be asking here:
>
> Why the rewrite in the first place? Is it because C is ugly and yucky and
> poopy? Why Chez Scheme and not, say, Chicken Scheme or GNU Guile?
>
> --
> 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.


[racket-users] Racket7 Conceit

2017-07-19 Thread Lehi Toskin
I've read through a few README's in the racket7 repo and I can't find anything 
specifically about *why* Racket is being implemented on top of Chez Scheme, so 
I suppose I'll be asking here:

Why the rewrite in the first place? Is it because C is ugly and yucky and 
poopy? Why Chez Scheme and not, say, Chicken Scheme or GNU Guile?

-- 
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] Example of file i/o?

2017-07-19 Thread Neil Van Dyke
Since newbies are always listening, I'll just mention something a lot of 
people here (including Greg) already know. :)


Something like `file->lines` is a handy convenience, when you know the 
file size won't break your system, and/or you're not writing reusable or 
long-lived code.


Good practice for important and reusable code often means doing this 
serial file processing as iteration (or folds) over the input port, and 
processing as you go, rather than sucking an entire file into memory first.


Not all line-based file-processing tasks are serial like this, but I'd 
guess that most are (or, even if you have to do some non-serial 
processing, it can usually be done in a more space-efficient way than 
representing the entire file in memory).


It's good to get comfortable with this.  You don't see it only in simple 
line-oriented file processing, but that's a good playground for 
learning.  Many software frameworks at the moment obscure computational 
time and space factors (and often hide massive loads of crud piled atop 
crud atop crud, especially in in client-side Web frameworks).  But your 
Racket programs are one environment in which you can often still have a 
pretty good idea of what's going on, and grow as a programmer.  If any 
newbies are not convinced, I'll just say "big data" here, as one 
buzzwordy example. :)  When, for example, we suddenly need to invent a 
way to decompose big data processing to use specialized compute 
clusters, that's a job for someone who can understand things, not 
someone who spent all their time only learning how to cargo-cult their 
way through someone else's crappy Web frameworks. :)


--
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] Example of file i/o?

2017-07-19 Thread Leith
That's exactly what I was trying to do - thanks!

On Wed, Jul 19, 2017 at 12:26 PM, Greg Hendershott <
greghendersh...@gmail.com> wrote:

> If you frequently want to deal with files as a list of lines, you
> could wrap the code Ben showed you in a function:
>
> (define (file->lines file)
>   (with-input-from-file file
> (λ ()
>   (for/list ([line (in-lines)])
> line
>
> As it happens, Racket already defines this function for you:
>
>   https://docs.racket-lang.org/reference/Filesystem.html#%
> 28def._%28%28lib._racket%2Ffile..rkt%29._file-~3elines%29%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] Example of file i/o?

2017-07-19 Thread Greg Hendershott
If you frequently want to deal with files as a list of lines, you
could wrap the code Ben showed you in a function:

(define (file->lines file)
  (with-input-from-file file
(λ ()
  (for/list ([line (in-lines)])
line

As it happens, Racket already defines this function for you:

  
https://docs.racket-lang.org/reference/Filesystem.html#%28def._%28%28lib._racket%2Ffile..rkt%29._file-~3elines%29%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] Catching duplicate identifiers.

2017-07-19 Thread Jens Axel Søgaard
To take care of shadowing you need to keep track of which identifiers are
declared in each internal definition context.
Here is one way to do it.
/Jens Axel


#lang racket
;;;
;;; Declarations
;;;

;; This is a demonstration of how to write a declaration (or definition)
;; form, that can raise a syntax error, if an identifier is declared twice
;; either at the module level or twice in the same internal defintion
context.

(require (for-syntax syntax/parse racket/format syntax/id-set))

(begin-for-syntax
  ; We need to keep track of two types of identifiers.
  ;  1. Identifiers declared at the module level
  ;  2. Identifiers declared locally (i.e. in an internal definition
context)

  ;;; 1. Module Level Identifiers

  ; The set of declared module-level identifiers is represented
  ; as an identifier set.
  (define module-level-ids (mutable-free-id-set))

  ; Declaring a new module level identifier amounts to adding the new
identifier to the set.
  (define (add-module-level-id! id)
(free-id-set-add! module-level-ids id))

  ; To see if an identifier is declared, just look it up.
  (define (declared-at-module-level? id)
(free-id-set-member? module-level-ids id))

  ;; 2. Local Identifiers
  ; Each internal definition context represents a scope.
  ; We need a hash table to keep track of the scopes.
  (define local-ids (make-hasheq))   ; all locally declared
identifiers
  ; The hash table is a map from internal definition contexts, to sets of
identifiers
  ; declared in that definition context.

  ; The contexts returned by syntax-local-context can't be used directly in
a hasheq -
  ; you have to use the first element which is guaranteed to eq? unique.
  (define (context-identity ctx) (car ctx))

  ; To check whether an identifier id is in a scope, given by a context ctx,
  ; we find the identifier set of the context, and check for membership.
  (define (id-in-this-context? ctx id)
(define ids (hash-ref local-ids (context-identity ctx) #f))
(and ids (free-id-set-member? ids id)))

  ; To add a new identifier to a local scope (an internal definition
context, ctx).
  ; is done by updating the hash table.
  (define (add-local-id! id ctx)
(define old-ids (hash-ref local-ids (context-identity ctx) #f))
(unless old-ids
  ; this context is new, so we must create the set
  (set! old-ids (mutable-free-id-set))
  (hash-set! local-ids (context-identity ctx) old-ids))
(free-id-set-add! old-ids id)
(hash-set! local-ids (context-identity ctx) old-ids))

  ; The hash table can be used to determine, if a given scope is new.
  (define (new-scope? ctx)
(hash-has-key? local-ids (context-identity ctx)))

  ; For debuging. Simply insert (displayln (serialize-locals)) where you
need it.
  (define (serialize-locals) ; for debug
(for/list ([(ctx-id ids) (in-hash local-ids)])
  (map syntax-e (free-id-set->list ids)

; SYNTAX (declare id)
;  Declare an identifier id.
(define-syntax (declare stx)
  (syntax-parse stx
[(_ id)
 ; Get the context in which the declare form was used.
 (define ctx (syntax-local-context))
 (cond
   ;; In a module context, the identifier is declared at the
module-level.
   [(eq? ctx 'module)
; Raise error, if the identifier has been declared previously.
(when (declared-at-module-level? #'id)
  (raise-syntax-error 'declare "identifier already declared in this
scope" stx #'id))
;; Otherwise it is a new variable, so we add it.
(add-module-level-id! #'id)
;; The declaration does nothing, so the expansion is (begin)
#'(begin)]
   [(list? ctx) ; internal definition context i.e. a local scope
(define seen-scope-before? (not (new-scope? ctx)))
(when (id-in-this-context? ctx #'id)
  (raise-syntax-error 'declare "identifier already declared in this
scope" stx #'id))
; we are now sure that the identifier haven't been declared before
(add-local-id! #'id ctx)
#'(void)]
   [else (raise-syntax-error
  'declare (~a "declarations are only allowed at the module
level "
   "and in internal definition contexts")
  stx)])]))

;;; Test
; Uncomment to see the duplicate errors.

(declare a)
(let ()
  (declare x)
  ; (declare x)
  (let ()
(declare s)
(declare t))
  ;(declare y)
  (declare y))
(declare b)
;(declare a)


2017-07-18 23:47 GMT+02:00 Sam Waxman :

> Thanks both for your replies, but it doesn't look like either of these
> will do exactly what I want. While the code keeping track of id's that you
> wrote comes close, it doesn't allow for shadowing. I still want racket to
> do everything that it used to do, so the program
>
>
> (define a 3)
> (let ()
>   (define a 4)
>   a)
>
> should still be valid. Shadowing is okay, I just can't have two duplicate
> identifiers in the same scope. I suppose I could use your code and clear
> the id-set every 

Re: [racket-users] Questions on HtDP 2e, Ex. 356

2017-07-19 Thread Matthias Felleisen

Hi Ben, 

as Jens has pointed out, it pays off to read the context of an exercise (like 
in the real world). The second exercise states 

> If the terminology poses any difficulties, do re-read BSL Grammar.

where “BSL Grammar” is a link that explains BSL via a data definition (that’s 
what a grammar is) and explains the terminology of 

— function application 
— function definition 

which are TWO distinct concepts. Sadly, math teachers gloss over this 
distinctions in school (if they know it) and other teachers do not know it. In 
computing, especially programming, precise terminology is critical so that you 
can efficiently communicate with others. After all, programming is a people 
discipline not a cubicle sport (even if you do sit in a cubicle in many shops; 
but that’s because of many other problems). 

So for your sake, I urge you to catch up on Intermezzo I so that you understand 
these distinctions. 

Having said that, I will move this sentence (hint) to the preceding exercise so 
that others don’t get hung up on this terminology issue. 

— Matthias


p.s. This explanation does probably not apply to people who just wish to learn 
to code and remain cheap rent-a-coders. But that’s a path they should choose 
after experiencing this fate for a couple of years in a company. 







> On Jul 12, 2017, at 10:58 PM, Ben Morin  wrote:
> 
> Hi Jens
> 
> Thanks for the reply.
> 
> I was working through it with some free time today, and I think my data 
> definition works. The other big problem I was having was the body for the 
> user-defined function. As you said, ex 356 isn't concerned about that aspect. 
> This is what was/is throwing me off. My assumption is now that I would define 
> the body of an arbitrary function in the arguments of eval-definition1.
> 
> For instance:
> 
> (eval-definition1 '(by-five (make-add 1 1)) 'by-five 'p (make-mul 5 'p))
> 
> The first arg being the expression to evaluate.
> Second is the function name being evaluated for.
> Third being 'by-five's parameter.
> Fourth being the actual body of 'by-five.
> 
> The result of eval-definition1 then being 10.
> 
> I hope this is heading in the right direction.
> 
> -- 
> 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.