Re: [racket-users] Racket Web servlet performance benchmarked and compared

2017-09-03 Thread antoine
A time ago i have implemented a minimal fastcgi protocol and compare it 
against various others implementations.


http://antoineb.github.io/blog/2015/06/02/basic-fastcgi-with-racket/


On 09/02/2017 10:12 PM, Neil Van Dyke wrote:

dbohdan wrote on 09/02/2017 03:12 PM:
I rather like the SCGI protocol. It's a pity that it isn't as widely 
supported as FastCGI, considering that it's much simpler to implement 
(second only to plain old CGI), but still has a performance profile 
similar to FastCGI's. 


I mostly implemented FastCGI in Racket at one point, but then I read 
about the FastCGI implementation in my target HTTP server having hard 
bugs, so I abandoned that.


I also think there are faster ways to serve HTTP from Racket, but I'd 
have to find funding to work through them.


And we have to keep in mind that, unlike benchmarks for LINPACK or 
standard transaction processing, the real-world applications of HTTP 
servers are messier.  And also, I don't think many people have been 
tuning for Web application benchmarks, unlike was once done for 
LINPACK and TP.  I think the Racket community has enough skill to make 
a respectable showing in a benchmark tuning war, or in general 
platform performance for real-world Web applications, but I'm not 
aware of any funding going into that right now.




--
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] Typed racket unreachable condition

2016-06-12 Thread antoine
The program didn't type check for clause 2 if i change for 999 for 
instance and i see something no feedback in drracket when the program 
typecheck.


I run racket 6.5 release and run 'raco pkg update --all' before testing, 
you both have probably a git version of typed-racket.

Anyway it's great to know that typed/racket could handle those cases.

PS: i don't know how to see the log, just grep typed-racket package for 
make-logger and see only 'TR-optimizer topic put nothing to be writed to 
:/.


On 06/12/2016 07:42 PM, Matthias Felleisen wrote:

Edit the program in DrRacket.

If you mouse over the ] of the cond clause, you will see ‘ret in clauses 1 and 
3 and nothing in clause 2. TR concluded that the result type is the empty set.

You can even replace ‘ret in clause 2 with p or 999, and the program still type 
checks. Again, this shows TR’s knowledge that the clause is about the empty set.

— Matthias





On Jun 12, 2016, at 1:32 PM, antoine  wrote:

Hello,

1 #lang typed/racket
2
3 (define-type Abc (U 'a 'b 'c))
4
5 (define (test [p : Abc]) : 'ret
6   (case p
7 [('a 'b) 'ret]
8 [('z) 'ret]
9 [else 'ret]))

This program type check, but the condition on line 8 is unreachable, is it 
possible for typed/racket to complain about it?

--
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] Typed racket unreachable condition

2016-06-12 Thread antoine

Hello,

 1 #lang typed/racket
 2
 3 (define-type Abc (U 'a 'b 'c))
 4
 5 (define (test [p : Abc]) : 'ret
 6   (case p
 7 [('a 'b) 'ret]
 8 [('z) 'ret]
 9 [else 'ret]))

This program type check, but the condition on line 8 is unreachable, is 
it possible for typed/racket to complain about it?


--
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] Routing syntax

2016-04-05 Thread antoine

I'm open to other ideas, but :variable is used in a number of routing string 
patterns in other languages/frameworks and seems fairly standard.


My point was being standard with other racket work not other web framework.


I'm not sure I understand how*limiting*  the constraint to be a regex is faster 
than*allowing*  the constraint to be a regex i.e. in either case, the URL needs to 
be parsed and then a function called > to compare a variable to a regex 
pattern. Am I misunderstanding?


The point is to make the routing use something like 
https://swtch.com/~rsc/regexp/regexp1.html to match a route, and thus 
can be done only if placeholder are regexp and not an arbitrary racket 
expression. (That is where the #:when comes if you can't express you 
constraints with regexp you could use a guard).


Using a list for expressing the pathinfo is the less limiting you can 
express "/product/item-:id" as ("product" ["item-" id]).

Antoher point you can use a symbol instead of a string removing the two ".

> That should be able to be checked at compile time via a macro, right?

It want something like:

"/some/route/:param"
#:when (equal? "abc" param)

instead of #:when (equal? "abc" (hash-ref some-predefine-binding "param"))

so it will exepand to something like:

(let ([param (hash-ref parameters "param")])
(equal? "abc" param))

On 04/04/2016 10:33 PM, Brian Adkins wrote:

On Apr 4, 2016, at 3:44 PM, antoine  wrote:

Hello,

I would go for 'methods instead of 'verbs, a HTTP vocabulary instead of a REST 
one.

Fair point. I suppose a couple additional characters won't kill me.


For the pathinfo:

When using a string you use :pattern as place holder as far as i know there is 
no such convention in racket, maybe you should explore ~pattern (like format), 
#:pattern, 'pattern, #'pattern (like macro templating) or at-expr?

I'm open to other ideas, but :variable is used in a number of routing string 
patterns in other languages/frameworks and seems fairly standard.


For constraints on placeholders you may want to limit them to regexp because:

1. 99.999% of the time they will satisfy the developer needs.
2. You give you room to make your router fast implementing a minimal final 
state machine (a regexp).

I'm not sure I understand how *limiting* the constraint to be a regex is faster 
than *allowing* the constraint to be a regex i.e. in either case, the URL needs 
to be parsed and then a function called to compare a variable to a regex 
pattern. Am I misunderstanding?

I probably didn't communicate very well with my example, but when I first 
started thinking about constraints, I assumed I'd follow the Rails idea of an 
elaborate construct to declare all the constraints, but then I thought that 
using a single lambda to indicate whether the route matched might be better. I 
figured syntax sugar can be added later for common cases. For example:

("/:org_shortname/product_image/:style/:filename" product-image
  #:methods get
  #:when verify-filename)

(define (verify-filename params)
   (regexp-match #rx".jpg$" (hash-ref params 'filename)))

or

("/:org_shortname/product_image/:style/:filename" product-image
  #:methods get
  #:when verify-filename-and-style)

(define (verify-filename-and-style params)
   (and
 (regexp-match #rx".jpg$" (hash-ref params 'filename))
 (exact-integer? (hash-ref params 'style


example:

("/~org-shortname/product_image/~style/~filename"
#:method POST
#:constraints ([filename ".*\\.xml$"])
;; a guard that break optimisations and expand
#:when (not (equal? "abc" org-shortname))
#:controller my-controller)

I'm not sure what you're suggesting here. Is your idea to provide both 
#:constraints and #:when ?


Or maybe use a list like dispatch-rule

((org-shortname "product_image" style filename)
#:method POST
#:constraints ([filename ".*\\.xml$"])
;; a guard that break optimisations and expand
#:when (not (equal? "abc" org-shortname))
#:controller my-controller)

The list style might disallow something like:

"/product/item-:id" e.g. /product/item-473

or

"/products/(*id).json" e.g. /products/foo/bar/baz.json => id = 'foo/bar/baz'


On 04/04/2016 08:08 PM, Brian Adkins wrote:

I've been looking into an appropriate syntax for routing web requests. For each 
route, I'll need the following information:

* URL Pattern (required) e.g.
   "/"
   "/:org_shortname/product_image/:style/:filename"
   "/:org_shortname/products/(*id).json"

* Function to handle request (required)

* Accepted HTTP verbs (optional, defaults ot all)

* Name (optional) - used to do "reverse routing" i.e. produce a URL from 
parameters

Re: [racket-users] Routing syntax

2016-04-04 Thread antoine

Hello,

I would go for 'methods instead of 'verbs, a HTTP vocabulary instead of 
a REST one.


For the pathinfo:

When using a string you use :pattern as place holder as far as i know 
there is no such convention in racket, maybe you should explore ~pattern 
(like format), #:pattern, 'pattern, #'pattern (like macro templating) or 
at-expr?


For constraints on placeholders you may want to limit them to regexp 
because:


1. 99.999% of the time they will satisfy the developer needs.
2. You give you room to make your router fast implementing a minimal 
final state machine (a regexp).


example:

("/~org-shortname/product_image/~style/~filename"
 #:method POST
 #:constraints ([filename ".*\\.xml$"])
 ;; a guard that break optimisations and expand
 #:when (not (equal? "abc" org-shortname))
 #:controller my-controller)


Or maybe use a list like dispatch-rule

((org-shortname "product_image" style filename)
 #:method POST
 #:constraints ([filename ".*\\.xml$"])
 ;; a guard that break optimisations and expand
 #:when (not (equal? "abc" org-shortname))
 #:controller my-controller)




On 04/04/2016 08:08 PM, Brian Adkins wrote:

I've been looking into an appropriate syntax for routing web requests. For each 
route, I'll need the following information:

* URL Pattern (required) e.g.
   "/"
   "/:org_shortname/product_image/:style/:filename"
   "/:org_shortname/products/(*id).json"

* Function to handle request (required)

* Accepted HTTP verbs (optional, defaults ot all)

* Name (optional) - used to do "reverse routing" i.e. produce a URL from 
parameters

* Contraints (optional) - further refine the pattern matching e.g. type/format 
of params

Here's an example from Rails:

Foo::Application.routes.draw do
   match "/:org_shortname/product_image/:style/:filename" => 
'product_images#product_image',
 :as => :product_image, :via => :get, :constraints => { :filename => 
/.jpg$/ }

   # URL pattern: "/:org_shortname/product_image/:style/:filename"
   # Function: ProductImagesController.product_image
   # Name: :product_image
   # Verbs: GET
   # Contraints: filename param must end in .jpg

   match '/products/(*id).json'  => 'products#show', :via => :get

   # URL pattern: '/products/(*id).json'
   #(*id) globs everything between /products/ and .json including / chars
   # Function: ProductsController.show
   # Verbs: GET
end

There are many other aspects (much of which is just syntax sugar) of routing in 
Rails that I'm ignoring initially.

I'm thinking of something like the following:

(routes
   ("/" home-page)
   ("/:org_shortname/product_image/:style/:filename" product-image #:verbs (get)
#:name prod-image #:when (regexp-match #rx".jpg$" filename))
   ("/products/(*id).json" product-show #:verbs (get)))

The first two arguments (url-pattern function) are required, so they're 
positional. The optional arguments are specified with keywords.

Instead of:  #:verbs (get)would it be better to have  #:verbs get  and 
dynamically check for an atom vs. list ?

My initial goal is just for the "base" syntax. Sugar can be added later for 
some cases.

  Any feedback is appreciated.

Thanks,
Brian



--
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] Standard web server interface?

2016-03-03 Thread antoine
There is the fastcgi protocol http://www.fastcgi.com/drupal/ (maybe it 
is underlying rack and wsgi).
I have done basic tests with it: 
http://antoineb.github.io/blog/2015/06/02/basic-fastcgi-with-racket/


I haven't found any racket implementation so far.

On 03/03/2016 04:16 PM, Brian Adkins wrote:

Is there anything analogous to Rack (Ruby) or WSGI (Python), i.e. a standard 
protocol between web servers and web applications, in the Racket world?

http://rack.github.io/

https://www.python.org/dev/peps/pep-/#abstract

Thanks,
Brian



--
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] Places performance & channel capacity

2016-01-21 Thread antoine
To make it clear here is what i have in mind:

#lang racket

;; dummy function, just remplace by A
(define (do-stuff shared-data data-length)
  (values
   (make-bytes data-length 65)
   data-length))

(define p
  (place ch
 (define shared-data (place-channel-get ch))
 (let loop ()
   (define data-length (place-channel-get ch))
   (define-values (new-data new-data-length) (do-stuff shared-data 
data-length))
   (bytes-copy! shared-data 0 new-data 0 new-data-length)
   (place-channel-put ch new-data-length)
   (loop

(module+ main
  (define shared-data (make-shared-bytes 10 66))
  (place-channel-put p shared-data)
  (place-channel-put p 5)
  (place-channel-get p) ;; 5
  (printf "~a\n" shared-data)  ;; AB
  (place-channel-put p 7)
  (place-channel-get p) ;; 7
  (printf "~a\n" shared-data)) ;; AAABBB

> But you would still need to copy the mutable byte string (returned by various 
> byte string functions) to the shared byte string you create with 
> make-shared-bytes, right? So, a byte string would still be copied.

Yes

> As someone suggested earlier, I could use read-bytes! and read directly into 
> a byte string created by make-shared-bytes. Then I *think* the cost to "send" 
> it to the worker place is minimal (maybe just sending a pointer). That would 
> require some buffer bookkeeping to split lines, etc., but the workers would 
> still need to copy their resulting byte strings to the output place.

Yes

> Maybe I'm being overprotective, but my hunch is that I need the output place 
> to serialize access to the output file vs. having the worker places write 
> directly to it, but if Racket serializes access to the output port, maybe I 
> can skip that.

According to the doc it seem you can't pass output-file-port.

-- 
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] Places performance & channel capacity

2016-01-21 Thread antoine
Bonjour,

Maybe for avoiding transforming mutable data to immutable data you could use
make-shared-bytes and transfer the data by this mean? Don't know the underlying
implementation of make-shared-bytes it didn't seem to use POSIX shared memory
objects.

Use one make-shared-bytes per place and synchronise between master place and a
child with the normal chanel communication.

-- 
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] values considered harmful

2015-09-13 Thread antoine
Bonjour,

The bytecode generated is:

(begin
  (module test 
(require (lib "racket/base.rkt"))
(provide)
(module configure-runtime 
  (require '#%kernel (lib "racket/runtime-config.rkt"))
  (provide)
  (print-as-expression '#t))
(define-values
 (_split&flip)
 (begin
   '%%inline-variant%%
   (#%closed
split&flip28
(lambda (arg0-30)
  '#(split&flip # 3 0 20 90 #f)
  (values (unsafe-cdr arg0-30) (car arg0-30
   (#%closed
split&flip27
(lambda (arg0-35)
  '#(split&flip # 3 0 20 90 #f)
  (values (unsafe-cdr arg0-35) (car (#%sfs-clear arg0-35)))
(define-values
 (_a _b)
 (let ((local40 (cons '0 '1)))
   (values (unsafe-cdr local40) (unsafe-car local40
(#%apply-values
 |_print-values:p@(lib "racket/private/modbeg.rkt")|
 (values (unsafe-cdr _b) (car _b)


Not familiar with the bytecode but a quick look at
http://docs.racket-lang.org/raco/decompile.html about %%inline-variant%% make me
think split&flip28 is over enthousiastic about

(values (unsafe-cdr arg0-30) (car arg0-30))

and should have generated:

(values (cdr arg0-30) (car arg0-30))

By the way it also segfault to me, 32bit, linux 6.2 release.

-- 
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] Sending RESTful Commands using Racket

2015-06-19 Thread antoine
Hello,

Use (define-values (a b c) (http-send-recv ...)) as a remplacement for define 
when you receive multiple values.
Or (let-values ([(a b c) (http-send-recv ...)]) ...) the same idea but for let.

You can search for binding ending with '-values'.

see 
http://docs.racket-lang.org/reference/eval-model.html?q=values#%28part._values-model%29
and 
http://docs.racket-lang.org/reference/values.html?q=values#%28def._%28%28quote._~23~25kernel%29._values%29%29

example:

(define-values (a b c) (values 1 2 3))
(define a (values 1 2 3)) ;; error expect one returned value get 3.

-- 
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] racket virtual machine

2015-06-05 Thread antoine
Hello,

Some links on the compilation of scheme to javascript:

https://41ac-a-698ebdfa-s-sites.googlegroups.com/a/loitsch.com/florian/publications/thesis.pdf?attachauth=ANoY7crN4qhkAC3xBCxnobzY3QFWCSKV_jYDgUmtf9IpDLUn72LZ0DY_eeoC0PXiRjkTpcxc9wWI3RmAjpkm7ZkKvqupWHu-nObTHRdoOKnDiLqEAnCDGbh-sYZzRib3Yiq5VVXTKgx3Pt7eRI6GJN1FVCirhUJoVUgSUHV-UORGGg6RS1xGWwXOevDq5KWQXp56F7l1xYveoCTxou7Euz6vCtyL9cZ9Jg%3D%3D&attredirects=0
http://wiki.call-cc.org/eggref/4/spock
http://users-cs.au.dk/danvy/sfp12/papers/thivierge-feeley-paper-sfp12.pdf


On Fri, Jun 05, 2015 at 12:37:18AM -0400, Neil Van Dyke wrote:
> Thanks, Jens Axel, Raoul, and Robby.
> 
> Different question... For support for writing polished Web browser (and
> PhoneGap) apps in Racket, any comments on which of the following two options
> is better (viable, easier to implement and maintain, better performance,
> etc.)?
> 
> 1. Implement Racket VM in JS, along with implementing support libraries in
> JS, and interpret `.zo` files at runtime.
> 
> 2. Forget about `eval`, require apps to be compilable on development host
> (but not necessarily runnable there), implement compiler from `.zo` to JS
> (managing TCO, etc.), implement small Racket runtime library in JS,
> implement browser facilities and/or GUI libraries in JS.  Later think about
> `eval`.[*]
> 
> [*] I've only done a very brief peek at sample `zo-parse` and `decompile`
> output, so I don't know how tricky it can get, but the little I saw looked
> like a static translation to JS wouldn't be too difficult.  I don't know how
> necessary `eval` is if you have bytecode, nor how much of the primitives
> would have to be implemented manually rather than translated from `.zo`.
> 
> Neil V.
> 
> -- 
> 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] Macro : Reify a function body definition

2014-08-23 Thread antoine
Hello,

If i understand well, you want to have access to the source code of foo.

Here is a program that give you the source code:

#lang racket

(define-syntax (define-equation stx)
  (syntax-case stx ()
[(_ (name . params) value ...)
 (begin
   (when (not (symbol? (syntax-e #'name)))
 (raise "not a symbol"))
   #`(begin (define #,(cons #'name #'params) value ...)
(define-for-syntax name (list (quote params) (quote value 
...)]))

(define-equation (foo x) (+ x (sin x)))
;; => (define (foo x) (+ x (sin x)))
;;(define-for-syntax foo '((x) (+ x (sin x

(define-syntax (derivate stx)
  (define sym (syntax-e (cadr (syntax-e stx
  (print (eval sym))
  ;;do the stuff you want here with the code
  #'1)

(derivate foo)

Two things to mentions:

- The source code data is given as a list of symbols instead of a syntax objects
  so you can't do free-identifier=?. You should rewrite define-equation with
  syntax-parse instead of syntax-case. But know just for the beginning i think
  you can live with that.

- I use eval inside derivate to fetch the data of foo at phase 1 i suspect it is
  not the right way to do it.

Hope it helps.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] Review request: Partially expanding to make "blue boxes"

2014-08-15 Thread antoine
Hello,

The other approch i see for munge-module.

Is to use:

(dynamic-require target-module 0)
(parameterize ([current-namespace (module->namespace target-module)])
  (expand-once a-module-level-stx))

Where a-module-level-stx is a form inside #%module-begin.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] plt web server

2014-06-19 Thread antoine
Hello,

I have done some little experiment 
https://github.com/antoineB/racket-examples/tree/master/not-restart-web-server.
If it helps.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] s-expression javascript syntax

2014-05-21 Thread antoine
Bonjour,

I have:
https://github.com/antoineB/racketjs/blob/master/js-ast.rkt

It is a straight forward javascript ast, intented to be used as intermediate
representation, so writing it by hand will not be convenient.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] Help with sockets.

2014-05-01 Thread antoine
http://www.w3.org/TR/xml/#sec-cdata-sect
http://www.w3.org/TR/xml/#NT-Char

Skimming the documentation, CDATA didn't help at all, nor escaping
http://www.w3.org/TR/xml/#dt-charref.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] Help with sockets.

2014-04-30 Thread antoine
To digress 

> The reason is because certain Strings can't be represented in the Text
> node of XML documents.  We ran across this problem in practice when
> students started writing programs and copying and pasting content from
> the web, which introduced characters like vertical tabs and other
> characters that can't be represented in XML text nodes.

What about CDATA, or escaping xml sequences? 

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] Overload #%module-begin

2014-02-26 Thread antoine
Hello,

I would like to change the expansion of a given module.

I tested:
;; abc.rkt
#lang racket
(require racket/stxparam)

(define-syntax-parameter param-abc #f)

(define-syntax-rule (enable-abc body ...)
  (#%plain-module-begin
   (syntax-parameterize ([param-abc #t])
body ...)))

(provide (rename-out [enable-abc #%module-begin])
 (except-out
  (all-from-out racket)
  #%module-begin))

;;edf.rkt
(module garage "abc.rkt"
   (define (a) 1))


When i do a "raco expand edf.rkt" i get:
begin (possibly implicit): no expression after a sequence of internal 
definitions
  in: (begin (define-values (a) (lambda () 1)))

I have no idea by who this begin is introduced?

My ultimate goal is to change the expansion result of a module given some 
parameters.
example:
(expand
  (transform-the-list
(read (open-input-file "some-file.rkt"))
params))

where transform-the-list will transform something like '(module bla bla 
(%module-begin ...)) into '(module bla bal (%module-begin (syntax-parameterize 
(...) ...))) 

But for now i am stick with the first problem :)

Thanks you.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] DB and named query parameters

2014-02-18 Thread antoine
Hello,

Ok it's a bit off topic, i was asking myself how much effort it could take to
make some sql statement typecheck at expansion time.

It takes me 1h30 to do this code, so it seem possible for you to do a subset of
sql that fit your project.

The main defect i see is the parser couldn't not take into account specific
Database sql. So other is it will take some work :).


#lang racket

(require parser-tools/yacc
 parser-tools/lex
 (prefix-in : parser-tools/lex-sre))

(module+ test
  (require rackunit))

(define-empty-tokens op-tokens
  (SELECT WHERE LIKE FROM ASTERISK BLANKS EOF LESS GREAT LESS-EQUAL GREAT-EQUAL 
COMMA EQUAL))

(define-tokens value-tokens
  (NAME PARAM NUMBER STRING))

(define (tokenize-string quote-char input-port)
  (define (recur data)
(define read/c (read-char input-port))
(cond
 [(eof-object? read/c) data]
 [(equal? #\\ read/c) (recur (string-append data (string read/c)
   (string (read-char input-port]
 [(equal? quote-char read/c) (string-append data (string read/c))]
 [else (recur (string-append data (string read/c)))]))
  (recur ""))

(define sql-lexer
  (lexer-src-pos
   ["select" 'SELECT]
   ["SELECT" 'SELECT]
   ["where" 'WHERE]
   ["WHERE" 'WHERE]
   ["like" 'LIKE]
   ["LIKE" 'LIKE]
   ["from" 'FROM]
   ["FROM" 'FROM]
   ["*" 'ASTERISK]
   ["=" 'EQUAL]
   ["<" 'LESS]
   ["<=" 'LESS-EQUAL]
   [">" 'GREAT] 
   [">=" 'GREAT-EQUAL]
   [#\, 'COMMA]
   [(:or #\space #\tab #\newline "\r") 'BLANKS]
   [(:: #\$ (:+ (:or (:/ #\0 #\9) (:/ #\a #\z) (:/ #\A #\Z) #\- #\_))) 
(token-PARAM lexeme)]
   [(:+ (:or (:/ #\a #\z) (:/ #\A #\Z) #\- #\_)) (token-NAME lexeme)]
   [(:: #\" (:+ (:or (:/ #\a #\z) (:/ #\A #\Z) #\- #\_)) #\") (token-NAME 
lexeme)]
   [(:+ (:/ #\0 #\9)) (token-NUMBER (string->number lexeme))]
   [#\' (let ([data (tokenize-string #\' input-port)])
  (token-STRING (string-append "'" data)))]
   [(eof) 'EOF]))

(define (lexer-thunk input-port)
  (port-count-lines! input-port)
  (define (this)
(let ([token (sql-lexer input-port)])
  (if (equal? (position-token-token token) 'BLANKS)
  (this)
  token)))
this)

(module+ test
  (define (input-port->list-token input-port #:blanks? [blanks? #f])
(let loop ([tokens '()])
  (let ([token (sql-lexer input-port)])
(case (position-token-token token)
  [(EOF) (reverse tokens)]
  [(BLANKS) 
   (loop
(if blanks?
(cons token tokens)
tokens))]
  [else
   (loop (cons token tokens))]
  
  (let ([data (input-port->list-token (open-input-string "SELECT * FROM 
my_table"))])
(check-equal? (position-token-token (first data)) 'SELECT)
(check-equal? (position-token-token (second data)) 'ASTERISK)
(check-equal? (position-token-token (third data)) 'FROM)
(check-equal? (token-name (position-token-token (fourth data))) 'NAME)))

(struct WhereExpr (op left right) #:transparent)

;; projection list? or 'all
(struct SelectStmt (projection table where) #:transparent)


(define sql-parser
  (parser
   (src-pos)
   (start select-statement)
   (end EOF)
   
   (tokens value-tokens op-tokens)
   
   (error (lambda x (print x)))
  
   (grammar
(select-statement
 [(SELECT ASTERISK FROM NAME) (SelectStmt 'all $4 #f)]
 [(SELECT ASTERISK FROM NAME WHERE where-expr) (SelectStmt 'all $4 $6)]
 [(SELECT project-list FROM NAME) (SelectStmt $2 $4 #f)]
 [(SELECT project-list FROM NAME WHERE where-expr) (SelectStmt $2 $4 $6)])
 
(project-list
 [(NAME) (list $1)]
 [(NAME COMMA project-list) (cons $1 $3)])

(where-expr
 [(NAME where-op PARAM) (WhereExpr $2 $1 $3)]
 [(NAME LIKE STRING) (WhereExpr 'LIKE $1 $3)]
 [(NAME where-op-number NUMBER) (WhereExpr $2 $1 $3)])

(where-op
 [(LIKE) 'LIKE]
 [(where-op-number) $1])

(where-op-number
 [(EQUAL) 'EQUAL]
 [(LESS) 'LESS]
 [(LESS-EQUAL) 'LESS-EQUAL]
 [(GREAT) 'GREAT] 
 [(GREAT-EQUAL) 'GREAT-EQUAL]


(define schema
  (hash "house" (hash "nb_door" number? "owner" string?)
"car" (hash "horse_power" number? "make"  string?)))

(define (schema-field-pred table field)
  (define fields (hash-ref schema table #f))
  (and fields
   (hash-ref fields field #f)))

(define (sql str)
  (define parsed 
(let ([oip (open-input-string str)])
  (begin0
(sql-parser (lexer-thunk oip))
(close-input-port oip
  (define where (SelectStmt-where parsed))
  (define pred
(and where
 (schema-field-pred (SelectStmt-table parsed)
(WhereExpr-left where
  (if pred
  (lambda (param)
(when (not (pred param))
  (raise "Don't match the condition"))
str)
  (lambda ()
str)))

(define my-query (sql "SELECT * FROM house WHERE nb_door = $nb"))

(my-query 12) ; =

Re: [racket] Delimiting scope

2014-01-21 Thread antoine
Bonjour,

I have tested this code:


#lang racket

(require
 (for-syntax racket))

(define-syntax (delimit-scope stx)
  (syntax-case stx ()
[(_ form)
 ((make-syntax-introducer)
  (datum->syntax #'here (syntax->datum #'form)))]))

(define z 13)

(let ([z 14])
  (delimit-scope
   z))



And it capture the module level binding.


So i have write another version, this one check all identifier from stx and
raise an exception if it is bind at module level:


#lang racket

(require
 (for-syntax racket))

(define-syntax (delimit-scope-bis stx)
  (syntax-case stx ()
[(_ form)
 (let ([marked (syntax-local-introduce (datum->syntax #'here (syntax->datum 
#'form)))])
   (if (and (identifier? marked)
(list? (identifier-binding marked)))
   (raise (format "~a cannot be lexical scoped" (syntax->datum marked)))
   (let loop ([lst (syntax->list marked)])
 (when (not (empty? lst))
   (let ([f (first lst)])
 (cond [(and (identifier? f)
 (list? (identifier-binding f)))
(raise (format "~a cannot be lexical scoped" 
(syntax->datum f)))]
   [(syntax->list f)
(loop f)])
   s)]))

(define a 13)

(let ([a 12])
  (delimit-scope-bis
   a))

uncaught exception: "a cannot be lexical scoped"


Is there a way to delimit module level bind using syntax mark mechanisme?
Can i view the syntax marks of a syntax object?

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] Parameters and servlets

2014-01-21 Thread antoine
Bonjour,

I think the parameterize approach didn't work because of:

(parameterize ([request-data (extract-the-data req)])
  (responce/output (lambda (out) (request-data

The lambda is put into a response struct, and the call to this
lambda is done outside the scope of the parameterize.


I am not sure to understand you about HTTP request.

I will explicit what i think is done (in the current implementation):

- Initialisation of a tcp connection
- Client sent an HTTP request
- Server create a thread (in the actual implementation) do the work and return 
a response
- end of tcp connection

Am i right?

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] matching behavior in dispatch-rules

2014-01-19 Thread antoine
Bonjour,

If you expand the code you get :

'(lambda (the-req)
   (syntax-parameterize
((bidi-match-going-in? #t))
(match
 the-req
 ((request/url
   (or #f "get")
   (url/paths (? string? temp1) "foo" (? string? temp3)))
  (test-route the-req temp1 temp3))
 ((request/url
   (or #f "get")
   (url/paths
(? string? temp4)
(? (λ (x) (equal? x "bar")) temp5)
(? string? temp6)))
  (test-route the-req temp4 temp5 temp6))
 (_ (default-else the-req)

So litteral string are not bind to any tempX.

I am not sure it answer your question.

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] Parameters and servlets

2014-01-18 Thread antoine
Bonjour,

I want use a parameter to store data with a request lifetime.

I first made a parameter
(define request-data (make-parameter #f))

That i fill in the main entry point for a servlet
(define (start req)
  (fill-request-data! req) 
  (treat req))

;; how i run the servlet for information
(serve
  #:port 8080
  #:dispatch (dispatch/servlet start))

(define (fill-request-data! req)
  (when (something-present-in req)
(request-data some-data)))

It seems to work well until i noticed that request-data isn't reset to #f for
each request. I thought that each new thread (Is there a new thread created for
each request?) will set request-data to its default.

So i decided to rewrite start as
(define (start req)
  (parameterize ([request-data #f])
(fill-request-data! req)
(treat req)))

But that don't works because i used responce/output and the proc arguments is 
out
parameterize scope, i don't when the response struct call its output fields.

So i have three solution:

rewrite
(define (start req)
  (request-data #f)
  (fill-request-data! req)
  (treat req))

Is there any defect in it? especialy regards to when the output fields is 
called?

rewrite my responce/output like

(let ([request-data-closurable (request-data)])
  (responce/output (lambda (out)  i can capture the value of 
request-data-closurable)))

or rewrite responce/output
(let ([data (do-the-rendering-here-and-now)])
  (responce/output (lambda (out) data)))

After writing this mail i remember threads inherits parameters but i am not sure
why i get a value different from #f.
Why not thread-cell for solution 1?

thank you.

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] Delimiting scope

2014-01-18 Thread antoine
Bonjour,

Is there a way to delimit scope?

example:
(let ([a 1])
  (delimit-scope
(let ([b 1])
  (+ a b
Give an error of the form 'a: undefined;'

I use the include-template from web-server/templates in a way like:
(response/output
  (lambda (out)
(display
  (include-template "my-template.html")
  out)))

"my-template.html" may also use include-template and i don't want an unexpected
bindings being used, i want to make bindings explicit.

I could use 
(let ([my-bindings])  (include-template "my-template.html"))
but this isn't sufficient for prevent upper bindings from let form being used.


Another point totally different.

In racket there is a lot of functions like response/output that take a function
in parameter that take n-parameters.
Why not use a macro unhygienic that introduce those n-bindings but allow user to
rename the bindings names:
(response/output
  #:out-binding 'abc
  (display "something" abc))

(response/output
  (display "something" out))


Thank you.

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] Implementing long polling ajax

2013-12-04 Thread antoine
Hello,

I was wondering how can i implement a long polling ajax technique (aka
comet) (https://en.wikipedia.org/wiki/Long_polling#Long_polling) using the
web-server lib.

So i need build a servlet that don't directly send a response but hold on in
place and wait for being wake up.

The only solution i ends up is using semaphore:

#lang racket

(require web-server/web-server
 web-server/http
 net/url
 web-server/managers/none
 (prefix-in seq:
web-server/dispatchers/dispatch-sequencer)
 (prefix-in filter:
web-server/dispatchers/dispatch-filter)
 web-server/servlet-dispatch)

(provide
 interface-version
 start
 manager)

(define interface-version 'v2)

(define manager
  (create-none-manager
   (lambda (req)
 (response/xexpr
  `(html (head (title "No continuation here"))
 (body (h1 "fycj you b")))

(define poll-hash (make-hash))

(define (poll1 req)
  (define params (map path/param-path (url-path (request-uri req
  (define id (second params))
  (define message (third params))
  (with-handlers ([(lambda (_) #t) (quick-response "fail" (format "There is no 
~a" id))])
  (let ([sem (hash-ref poll-hash id)])
(hash-set! poll-hash id message)
(semaphore-post sem))
  (quick-response "ok" "message transmitted")))
  
(define (push1 req)
  (define params (map path/param-path (url-path (request-uri req
  (define id (first params))
  (define sem (make-semaphore 0))
  (hash-set! poll-hash id sem)
  (semaphore-wait sem)
  (begin0 
(quick-response
 "ok"
 (hash-ref poll-hash id))
(hash-remove! poll-hash id)))


(serve
 #:port 8080
 #:dispatch 
 (seq:make
  (filter:make
   #rx"/poll"
   (dispatch/servlet poll1))
  (dispatch/servlet push1)))

(do-not-return)

A bit of explanation of the code:

- we hit push1 with a request of type /ID
- there is no response from the server
- we hit poll1 with a request of type /ID/MESSAGE
- this increment the semaphore associated with ID and pass MESSAGE inside the 
poll-hash
- then the previous push1 request can return

Is there other way to do?

I first think using a continuation, but capture continuation still return
something and don't hold the computation.

What is the cost of using a semaphore?

Thanks you in advance for your responses.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] How to make racket to show the call stack when get an exception?

2013-11-23 Thread antoine
Bonjour,

For having the stack trace you need to use the errortrace library 
http://docs.racket-lang.org/errortrace/.

If you run drracket you can activate it or not when you choose the language.

If you run geiser you can put "(require errortrace)" in ~/.racket-geiser.

If you run from the command line so "racket -l errortrace my-script.rkt" will 
show you the stacktrace.

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] Developing a Recursive Descent Parser in Racket

2013-10-24 Thread antoine
I have built a php parser with the racket yacc like tools and i am pretty happy 
with it.

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] Contracts error message

2013-09-08 Thread antoine

Hello,

I have just start using contracts in racket, but i am a bit disapointed 
by the

error message they give to me.

example contract error:

 add-number: contract violation
 expected: number?
 given: "1"
 in: the 2nd argument of
  (-> number? number? number?)
 contract from: abc.rkt
 blaming: edf.rkt
 at: abc.rkt:5.3

I would have expected to have the line and column number in the blaming line
like what you could get from a stacktrace.

Is it possible in contracts?
Am i the only one to complain? :)

Thanks you in advance.

 Racket Users list:
 http://lists.racket-lang.org/users


[racket] Typed racket with serializable struct

2013-09-06 Thread antoine

Hello,

I would like to use a 'serialize-struct' in typed/racket.  It seems 
there is no

'serialize-struct:' built in typed/racket.

So i have decided to put the struct into a specific submodule and 
require/type

the structs.

;;test.rkt
#lang typed/racket

(module data-structs racket
  (require racket/serialize)

  (serializable-struct ArrayType (expr) #:transparent)

(provide struct:ArrayType ArrayType? ArrayType ArrayType-expr))

(require/typed 'data-structs
  [#:struct ArrayType
([expr : Integer])])
;;test.rkt

I get this errors which i can't understand:

link: module mismatch;
 possibly, bytecode file needs re-compile because dependencies changed
  importing module: 'phpdoc-struct
  exporting module: 'phpdoc-struct
  exporting phase level: 0
  internal explanation: variable not provided (directly or indirectly)
  at: ArrayType2
  in: ArrayType.17

Note that if i use two file it works.
Note if i use (provide (struct-out ArrayType)) i get the following error:

phpdoc-struct.rkt:6:23: module: provided identifier not defined or 
imported for phase 0

  at: ArrayType
  in: (#%module-begin (#%require racket/serialize) (define-values 
(struct:ArrayType ArrayType1 ArrayType? ArrayType-expr) (let-values 
(((struct: make- ? -ref -set!) (letrec-syntaxes+values 
(((struct-field-index12) (convert-renamer (lambda (stx) (syntax-case s...


I have no idea of what happen?


 Racket Users list:
 http://lists.racket-lang.org/users


Re: [racket] Binding undefined with a macro

2013-09-03 Thread antoine
I have grasp the problem i have expanded the file and narrow the region 
concerned and get :


(define-values
(struct:person person1 person? person-name person-nickname) ; 
define here

(let-values (((struct: make- ? -ref -set!)
  (let-values ()
(let-values ()
  (#%app
   make-struct-type
   'person
   '#f
   '2
   '0
   '#f
   (#%app list (#%app cons prop:insiders 
person-name)) ; accessed here

   (#%app current-inspector)
   '#f
   '(0 1)
   '#f
   'person)
  (#%app
   values
   struct:
   make-
   ?
   (#%app make-struct-field-accessor -ref '0 'name)
   (#%app make-struct-field-accessor -ref '1 'nickname

We see that person-name is accessed before it definition.

So i rewrite the macro :

(define-syntax (struct-abc stx)
   (syntax-case stx ()
 [(_ sname (name args ...) props ...)
  (with-syntax ([sname-name (format-id #'sname "~a-~a" #'sname 
#'name)])

  #`(struct sname (name args ...) props ...
  #:property prop:insiders sname-name))]))

to :

(define-syntax (struct-abc stx)
   (syntax-case stx ()
 [(_ sname (name args ...) props ...)
  (with-syntax ([sname-name (format-id #'sname "~a-~a" #'sname 
#'name)])

  #`(struct sname (name args ...) props ...
  #:property prop:insiders (lambda () sname-name)))]))


I don't know if there is another way to do this sort of recursive 
binding without a lambda.


Thanks for you reply it helps me point out the problem.

On 03/09/2013 18:36, J. Ian Johnson wrote:

The struct form generates names unhygienically, but predictably. You will have 
to have a handle on both the struct name and field name to produce an 
identifier equal to the generated field accessor.
In your case, if you can commit to name always being given first (there are 
ways around this that involve more parsing), then the following will allow you 
to write your macro correctly:

(require (for-syntax racket/syntax))
(define-syntax (struct-abc stx)
(syntax-case stx ()
  [(_ sname (name args ...) props ...)
   (with-syntax ([sname-name (format-id #'sname "~a-~a" #'sname #'name)])
   #`(begin
   (+ 1 1)
   (struct sname (name args ...) props ...
   #:property prop:insiders sname-name)))]))

-Ian
- Original Message -
From: "antoine" 
To: users@racket-lang.org
Sent: Tuesday, September 3, 2013 12:23:17 PM GMT -05:00 US/Canada Eastern
Subject: [racket] Binding undefined with a macro

Hello,

With this macro:

(define-syntax (struct-abc stx)
(syntax-case stx ()
  [(_ name (args ...) props ...)
   #`(begin
   (+ 1 1)
   (struct name (args ...) props ...
   #:property prop:insiders person-name))]))

(define-values (prop:insiders insiders? insiders-ref)
(make-struct-type-property 'insider))


When i do :

(struct-abc person (name nickname))

I get :

person-name: undefined;
   cannot reference an identifier before its definition

But i know that person-name is defined the problem come from 'begin' in
the macro, if i rewrite like this :

(define-syntax (struct-abc stx)
(syntax-case stx ()
  [(_ name (args ...) props ...)
   #`(struct name (args ...) props ...
   #:property prop:insiders person-name)]))

It works as expected.

So my question are:

Could you explain (point out) me why the person-name is unknown at this
point?
And how can i change the begin with something like '#,@'?

Thank you.

   Racket Users list:
   http://lists.racket-lang.org/users



 Racket Users list:
 http://lists.racket-lang.org/users


[racket] Binding undefined with a macro

2013-09-03 Thread antoine

Hello,

With this macro:

(define-syntax (struct-abc stx)
  (syntax-case stx ()
[(_ name (args ...) props ...)
 #`(begin
 (+ 1 1)
 (struct name (args ...) props ...
 #:property prop:insiders person-name))]))

(define-values (prop:insiders insiders? insiders-ref)
  (make-struct-type-property 'insider))


When i do :

(struct-abc person (name nickname))

I get :

person-name: undefined;
 cannot reference an identifier before its definition

But i know that person-name is defined the problem come from 'begin' in 
the macro, if i rewrite like this :


(define-syntax (struct-abc stx)
  (syntax-case stx ()
[(_ name (args ...) props ...)
 #`(struct name (args ...) props ...
 #:property prop:insiders person-name)]))

It works as expected.

So my question are:

Could you explain (point out) me why the person-name is unknown at this 
point?

And how can i change the begin with something like '#,@'?

Thank you.

 Racket Users list:
 http://lists.racket-lang.org/users


Re: [racket] syntax-parse form at runtime

2013-08-29 Thread antoine

On 28/08/2013 23:27, Ryan Culpepper wrote:

On 08/28/2013 04:59 PM, antoine wrote:

Hello,

I would like play with macros, and for keep it as simple as possible i
decided
to work with macro at runtime, i just pass the arguments encapsulated 
in a

syntax object.

But with the code under i get :

test.rkt:8:16: syntax-parse: literal is unbound in phase 0 (phase 0
relative to the enclosing module)
   at: abc
   in: (syntax-parse stx #:literals (abc) ((abc elem:id ...+) (syntax 
1)))


Could you help me to decypher it ?


syntax-parse (unlike syntax-rules and syntax-case) considers it an 
error to specify a literal that has no binding. You can read my 
thoughts on the subject here:


http://macrologist.blogspot.com/2011/09/macros-and-literals.html
http://macrologist.blogspot.com/2011/09/syntax-parse-and-literals.html

There are two ways to fix your code.

One way is to just add a definition of abc, any definition. If abc 
doesn't have any meaning by itself, the usual idiom is a macro 
definition that always raises an error:


  (define-syntax abc
(lambda (stx)
  (raise-syntax-error #f "not used as part of a parse-a form" stx)))

Then your macro/function will recognize identifiers that refer to that 
binding of abc. Which means, for example, that if you want code in 
other modules to use your macro, you need to provide abc.


The other way is to change your code to use #:datum-literal or ~datum 
to recognize the identifier symbolically. But in that case, maybe a 
keyword (eg #:abc) would be better.


Ryan



I far as i understand it seems the '#:literals (abc)' put this into a
binding
'literal' which is not available at runtime.

Thank you.

;;test.rkt
#lang racket

(require
  syntax/parse)

(define (parse-a stx)
   (syntax-parse stx
 #:literals (abc)
 [(abc elem:id ...+)
  #'1]))

(parse-a #'(abc a b c))
;;test.rkt


  Racket Users list:
  http://lists.racket-lang.org/users




Thanks you.

I will use #:datum-literal.

 Racket Users list:
 http://lists.racket-lang.org/users


[racket] syntax-parse form at runtime

2013-08-28 Thread antoine

Hello,

I would like play with macros, and for keep it as simple as possible i 
decided

to work with macro at runtime, i just pass the arguments encapsulated in a
syntax object.

But with the code under i get :

test.rkt:8:16: syntax-parse: literal is unbound in phase 0 (phase 0 
relative to the enclosing module)

  at: abc
  in: (syntax-parse stx #:literals (abc) ((abc elem:id ...+) (syntax 1)))

Could you help me to decypher it ?

I far as i understand it seems the '#:literals (abc)' put this into a 
binding

'literal' which is not available at runtime.

Thank you.

;;test.rkt
#lang racket

(require
 syntax/parse)

(define (parse-a stx)
  (syntax-parse stx
#:literals (abc)
[(abc elem:id ...+)
 #'1]))

(parse-a #'(abc a b c))
;;test.rkt


 Racket Users list:
 http://lists.racket-lang.org/users


Re: [racket] Use `set!' or not in this scenario?

2013-07-19 Thread Antoine Noo
Hello,

as an extension of the question of Ben.

(define (func args)
  (define result init-data)
  (define (loop args-loop)
...
(set! result some-data)
)
  (loop args)
  result)

Is this a good practice?
And if you ask why don't directly return loop, it is for the case to make
recursive call every where in the function not only in terminal possition.



2013/7/19 Joe Marshall 

> You could also hide the data with a monad.
> On Jul 19, 2013 9:35 AM, "Carl Eastlund"  wrote:
>
>> One common solution to this issue is a parameter:
>>
>> (define current-data (make-parameter #f))
>>
>> (define (f1 the-data ...)
>>   (parameterize ([current-data the-data])
>> (f2 ...)))
>>
>> (define (f2 ...)
>>   ... (f3 ...) ...)
>>
>> ...
>>
>> (define (fx ...)
>>   ... (current-data) ...)
>>
>> The parameterize form in f1 means that calls to (current-data) will
>> produce the-data during the dynamic extend of f1 (meaning from the time f1
>> is called until it returns).  This isn't just a set! on enter and exit;
>> different threads won't see this change, for instance, and if f1 is
>> exited/re-entered using a continuation, (current-data) will only produce
>> the-data while inside f1.  So while it's not purely functional, it's a much
>> more disciplined kind of effect.
>>
>> Carl Eastlund
>>
>> On Fri, Jul 19, 2013 at 12:23 PM, Ben Duan  wrote:
>>
>>> Scenario: A piece of data is determined in the first function `f1', but
>>> is only processed in a sub-sub-sub-… function `fx'.
>>>
>>> One way is to use pass `the-data' as arguments from `f1' through `f2'
>>> all the way down to `fx':
>>>
>>> (define f1 (the-data …)
>>>   …
>>>   (f2 the-data …)
>>>   …)
>>>
>>> (define f2 (the-data …)
>>>   …
>>>   (f3 the-data …)
>>>   …)
>>>
>>> …
>>>
>>> (define fx (the-data …)
>>>   … the-data …)
>>>
>>> But in the above way, the body of `f2', `f3', `f4' and so on doesn't
>>> use `the-data'. It is only passed to the next function. And I still have to
>>> add the argument `the-data'.
>>>
>>> Another way is to use `set!':
>>>
>>> (define the-data …)
>>>
>>> (define f1 (the-data …)
>>>   …
>>>   (set! the-data …)
>>>   …
>>>   (f2 …)
>>>   …)
>>>
>>> (define f2 (…)
>>>   …
>>>   (f3 …)
>>>   …)
>>>
>>> …
>>>
>>> (define fx (…)
>>>   … the-data …)
>>>
>>> But in this way, the benefits of being functional are lost. For example
>>> there will be some problems writing tests for these functions.
>>>
>>> My question is, which way is better? Or are there other ways to solve
>>> this problem?
>>>
>>> Thanks,
>>> Ben
>>>
>>> P.S. This question is not about Racket. It's just a beginner's question
>>> about how to program. Please let me know if it's not appropriate to ask
>>> this kind of questions here. Thank you.
>>>
>>> 
>>>   Racket Users list:
>>>   http://lists.racket-lang.org/users
>>>
>>>
>>
>> 
>>   Racket Users list:
>>   http://lists.racket-lang.org/users
>>
>>
> 
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
>

  Racket Users list:
  http://lists.racket-lang.org/users