Re: [racket-users] Re: Structured Concurrency in Racket

2019-10-10 Thread Zelphir Kaltstahl
Hi!

Hmmm, that code example looks simple enough. If that works for arbitrary
serializable-lambda with only serializable parts, I could continue my
process pool project. The only issue would then be, that any user of it
would have to know in advance, that they cannot define their lambdas as
usual, but have to use serializable-lambda, potentially through their
entire code (as there might be references to things which contain
references to things, which ...). The abstraction is in this way leaky,
but it would make a working library then.

`n` does not need to be serializable, because it is defined in the
module and will be defined in the module "on the other side" as well? If
I understand this correctly.

When saying, that in other languages it is possible to simply define a
lambda and send it to another actor, I meant of course with immutable
data, or at least with data, which is not actually mutated. I assumed
that already, but yes, of course you are right about that. I was
thinking of Erlang, Elixir and maybe Pony.

When hearing actors, then Threads could be thought of a means of
implementing them, but I think might not be useful to do so when
thinking about performance. Architecturally yes, maybe. That is, why I
would think of places as a means of implementing an actor model kind of
thing.

When you say, that loci extends the idea of places to multiple machines,
what do you mean? I thought places can already run on multiple machines.

I might try to use your example code to finally finish the process pool
implementation I started. If everything works like that, then I probably
have to retract any statements about parallelism being too hard in
Racket : ) It would be nice however, to not have to use a different
construct to define serializable lambdas and to be able to go to any
program and simply use existing lambdas to send them to a process pool
to make use of multiple cores, instead of having to refactor many things
into serializable things.

Regards,

Zelphir


On 10/9/19 11:58 PM, Philip McGrath wrote:
> On Wed, Oct 9, 2019 at 2:09 PM Zelphir Kaltstahl
> mailto:zelphirkaltst...@gmail.com>> wrote:
>
> I was wrongly under the impression, that serializable-lambda are
> supposed to work out of the box, when sending them over channels,
> without needing to do any further work ("are serialized
> automatically" instead of "can be serialized"). … If you know how
> to serialize those serializable-lambdas, it is possible, that you
> could solve the problems they faced.
>
> … Is there a generic way to serialize such lambdas, no matter what
> they look like?
>
> You can serialize the procedures produced by `serial-lambda` using the
> `racket/serialize
> <https://docs.racket-lang.org/reference/serialization.html>` library,
> the same way you serialize other kinds of Racket values. Here is an
> extended example:
> #lang racket
>
> (require web-server/lang/serial-lambda
>          racket/serialize
>          rackunit)
>
> (define (make-serializable-adder n)
>   (serial-lambda (x)
>     (+ n x)))
>
> (define serializable-add5
>   (make-serializable-adder 5))
>
> ;; The value of a serial-lambda expression is a procedure.
> (check-eqv? (serializable-add5 2)
>             7)
>
> ;; The procedure can't be sent over a place-channel directly ...
> (check-false
>  (place-message-allowed? serializable-add5))
> ;; ... but it is serializable:
> (check-true
>  (serializable? serializable-add5))
>
> (define serialized
>   (serialize serializable-add5))
> ;; The serialized form can be sent over a place-channel.
> (check-true
>  (place-message-allowed? serialized))
>
> (define-values [in out]
>   (place-channel))
>
> (place-channel-put in serialized)
>
> ;; When we deserialize the received value, potentially in a new place ...
> (define received
>   (place-channel-get out))
> (define deserialized
>   (deserialize received))
>
> ;; ... it works like the original, including closing over the lexical
> environment.
> (check-eqv? (deserialized 11)
>             16)
>
> One thing to note is that the procedures returned by `serial-lambda`
> do close over their lexical environments, which is desirable for the
> reasons you mention in your previous message. That means that values
> which are captured as part of the closure must also be serializable,
> or `serialize` will raise an exception. (The same is true for lists:
> they are serializable as long as their contents are also serializable.)
>
> Concretely, in the example above, `n` is part of the closure and
> therefore must be serialized—which works out great, because `n` must
> be a number, and numbers are serializable. On the other hand, the
> procedure `+` isn't serializable, but that's ok

Re: [racket-users] Re: Structured Concurrency in Racket

2019-10-09 Thread Zelphir Kaltstahl
Hi George!

I was wrongly under the impression, that serializable-lambda are
supposed to work out of the box, when sending them over channels,
without needing to do any further work ("are serialized automatically"
instead of "can be serialized"). This is what I would have expected, as
it seems to be the case in other programming languages, where one can
simply send lambdas to other actors, which can, but don't have to, run
on other cores or other machines. A year ago or so there was an Racket
event in Berlin (Racket Summerfest), where people also tried to use
serializable-lambda to send them over channels, but did not succeed. I
do not know what the problems there were, as I did not attend that
specific workshop. However, I think some of the more knowledgeable
people of the Racket community might remember that workshop. Maybe there
also was some code from that event. If you know how to serialize those
serializable-lambdas, it is possible, that you could solve the problems
they faced.

I have a question regarding what you wrote: Is there a generic way to
serialize such lambdas, no matter what they look like?

I think that would be kind of necessary to abstract away the painful
points of coming up with a way of serializing the lambdas. It also seems
to be necessary for eventually creating a library, which provides a
process pool, as such library possibly should be easy to use and not
force the user to think about difficult thing, when the intention the
user has seems so simple "just do that on another core".

I have not read CSP and I know, that it is considered to be _the_
standard for multi processing, that much I have to admit. I am also not
trying to argue the concept away : ) Just saying, that in Racket it is
quite difficult (at least for me, although I have tried many hours, when
I was working on my project) to get multi processing done. I believe in
Python at least superficially one faces a similar situation: Threads on
same core, processes can go on other core, which is the parallel to
starting a new Racket VM, because it also starts a new Python process.
However, somehow it is easily possible to give a reference or a lambda
to a process pool in Python. I don't know the implementation details of
course.

Best regards,

Zelphir


On 10/9/19 1:36 PM, George Neuner wrote:
> 1) Serial lambdas and closures are in web-server-lib, not the
> framework.  What is the problem including a library?
>
> 2) /serial-lambda/, /define-closure/, etc.  only create functions that
> CAN BE serialized.  You still do have to (de)serialize them.
>
> 3) You can send serialized code over place channels - it is just a
> string.
>
>
> The difficulty in sending code is making sure all the support context
> is available.  To be sure, this can be a pain.  But consider that for
> a local place you can send the name of a code file to dynamic-require
> ... and for a remote place you can send the file itself.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/0dbba335-fc99-b392-bc9b-2ad7736bf9ab%40gmail.com.


Re: [racket-users] Re: Structured Concurrency in Racket

2019-10-09 Thread Zelphir Kaltstahl
True. However, here comes the big "but": What about capturing the
environment of expressions? For example I might have identifiers in my
S-expressions bound to potentially a lot of data, which must also be
send through the channel. It would be painful (if not impossibly at the
time of writing the code) to have to copy the whole representation (of a
creating expression) for that data into an expression to send it.

On 10/9/19 11:26 AM, David Storrs wrote:
> Note that it's possible to send S-expressions through a channel and
> then eval them on the far end. This would let you do something like this:
>
> (hash 'func 'my-predefined-lambda 'args '(arg1 arg2))
>
> Which calls a predefined function, or:
>
> (hash 'install '(lambda (username) (displayln (~a "Hello, "
> username))) 'name 'greet)
>
> Which defines a new function and installs it for later use under the
> name "greet".
>
> It's not elegant and it has all the usual problems with eval'ing code,
> but it's possible.
>
> On Wed, Oct 9, 2019, 2:34 AM Zelphir Kaltstahl
> mailto:zelphirkaltst...@gmail.com>> wrote:
>
> I don't think places are a good example for good support of
> parallelism.
>
> It is difficult to get a flexible multi processing implementation
> done,
> without hard-coding the lambdas, that run in each place, because we
> cannot send serializable lambdas (which also are not core, but only
> exist in the web server package) over channels. That means, that one
> needs to define ones lambdas ahead of time before even starting a
> place
> and sending it the data to process. That means, that we cannot have
> something like a process pool.
>
> The other problem is, that using places means using multiple
> Racket VMs,
> if I remember correctly, which uses some RAM. It is not like
> places are
> super lightweight at least.
>
> Racket threads run on a single core, I think.
>
> I know there is a tutorial about using futures somewhere, where it
> depends on the number type one uses, whether the code can be
> automatically run in parallel or not, so there is also some issue
> there,
> or at least it did not look to me like one could use futures
> everywhere
> and have neat parallelism.
>
>
> When I tried to write a process pool kind of thing (had a lot of help
> from this mailing list!), which I called work distributor, the above
> mentioned problems with lambdas caused me to abandon that project,
> until
> I can send lambdas over channels.
>
> Correct any of the things I wrote above, if they are not true, but I
> think Racket definitely needs a better multi processing story. I would
> love to see something like Guile Fibers. Andy Wingo even mentioned in
> his video, that some of the Racket greats advised him to look at
> Concurrent ML and that that is where he got some ideas from, when
> implementing Guile Fibers as a library. Shouldn't Racket then be
> able to
> have a similar library? I don't understand how Fibers really
> works, but
> that is a thought I had many times, since I heard about the Fibers
> library.
>
> Regards,
>
> Zelphir
>
> -- 
> 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
> <mailto:racket-users%2bunsubscr...@googlegroups.com>.
> To view this discussion on the web visit
> 
> https://groups.google.com/d/msgid/racket-users/59c68f8e-b668-f08e-55ae-a977084f5bb1%40gmail.com.
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/b0f5aa40-31f6-ebca-284d-30fc58e2390c%40gmail.com.


[racket-users] Re: Structured Concurrency in Racket

2019-10-09 Thread Zelphir Kaltstahl
I don't think places are a good example for good support of parallelism.

It is difficult to get a flexible multi processing implementation done,
without hard-coding the lambdas, that run in each place, because we
cannot send serializable lambdas (which also are not core, but only
exist in the web server package) over channels. That means, that one
needs to define ones lambdas ahead of time before even starting a place
and sending it the data to process. That means, that we cannot have
something like a process pool.

The other problem is, that using places means using multiple Racket VMs,
if I remember correctly, which uses some RAM. It is not like places are
super lightweight at least.

Racket threads run on a single core, I think.

I know there is a tutorial about using futures somewhere, where it
depends on the number type one uses, whether the code can be
automatically run in parallel or not, so there is also some issue there,
or at least it did not look to me like one could use futures everywhere
and have neat parallelism.


When I tried to write a process pool kind of thing (had a lot of help
from this mailing list!), which I called work distributor, the above
mentioned problems with lambdas caused me to abandon that project, until
I can send lambdas over channels.

Correct any of the things I wrote above, if they are not true, but I
think Racket definitely needs a better multi processing story. I would
love to see something like Guile Fibers. Andy Wingo even mentioned in
his video, that some of the Racket greats advised him to look at
Concurrent ML and that that is where he got some ideas from, when
implementing Guile Fibers as a library. Shouldn't Racket then be able to
have a similar library? I don't understand how Fibers really works, but
that is a thought I had many times, since I heard about the Fibers library.

Regards,

Zelphir

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/59c68f8e-b668-f08e-55ae-a977084f5bb1%40gmail.com.


Re: [racket-users] Name of undefined identifier as string in macro

2019-08-04 Thread Zelphir Kaltstahl
Thank you!

I am not 100% sure I understood all about the different phases, but I
seem to have semi-understood and am able to use my understanding
combined with a little trial and error.

I've now got it working as follows:

#+BEGIN_SRC racket
#lang racket

(require (for-syntax racket/string))

(define-syntax define-api-route
  (lambda (stx)
    (define (identifier-name->string id)
  (symbol->string (syntax->datum id)))

    (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
  [(_ route GET my-content-type)
   (string-contains? (identifier-name->string (syntax route)) "abc")
   (syntax (quote aaa))]
  ;; an else branch basically
  [(_ route GET my-content-type) #t
   (syntax (quote bbb))])))
#+END_SRC

However, the actual code is supposed to define some procedures. This
would be quite long all in one
macro. So I want to call another procedure in the cases of syntax-case.
In this other macro, `identifier-name->string` will not be available, so
I want to give the other macro already the route as string, which will
be used to send requests to an API.

#+BEGIN_SRC racket
#lang racket

(require (for-syntax racket/string))

(define-syntax define-api-route
  (lambda (stx)
    (define (identifier-name->string id)
  (symbol->string (syntax->datum id)))

    (define (identifier->symbol id)
  (syntax->datum id))

    (define another-macro
  (lambda (route http-method my-content-type route-as-string)
    (syntax (quote bbb

    (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
  [(_ route GET my-content-type)
   (string-contains? (identifier-name->string (syntax route)) "abc")
   (syntax (quote aaa))]
  ;; an else branch basically
  [(_ route GET my-content-type) #t
   (another-macro (syntax route)
  'GET
  (syntax my-content-type)
  (identifier-name->string (syntax route)))])))
#+END_SRC

This works, but I was hoping to be able to not define everything inside
one macro, but instead split it up into multiple parts. Just imagine how
big that one macro could become. For example something like:

#+BEGIN_SRC racket
#lang racket

(require (for-syntax racket/string))

(define define-simple-api-route
  (lambda (route http-method my-content-type route-as-string)
    (syntax (quote bbb

(define-syntax define-api-route
  (lambda (stx)
    (define (identifier-name->string id)
  (symbol->string (syntax->datum id)))

    (define (identifier->symbol id)
  (syntax->datum id))

    (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
  [(_ route GET my-content-type)
   (string-contains? (identifier-name->string (syntax route)) "abc")
   (syntax (quote aaa))]
  ;; an else branch basically
  [(_ route GET my-content-type) #t
   (define-simple-api-route (syntax route)
    'GET
    (syntax my-content-type)

    (identifier-name->string (syntax
route)))])))
#+END_SRC

But then the procedure `define-simple-api-route` will not be defined for
use in the syntax-case.

You already mentioned the `begin-for-syntax`. However, it is Racket
specific and not available in for example Guile Scheme or other Schemes.
I guess I will have to put things in separate modules then. Or is there
any other way?



On 8/3/19 11:53 AM, Ryan Culpepper wrote:
> On 8/3/19 10:48 AM, Zelphir Kaltstahl wrote:
>> Hi!
>>
>> I am trying to write a macro, which checks the name of an argument
>> for presence a substring. This is not the main purpose of the macro,
>> but I want to do different things depending on the substring being
>> contained or not contained.
>>
>> Here is what I've got so far:
>>
>> ~
>> ;; A macro to get the identifier name as string, shamelessly copied
>> from StackOverflow and renamed:
>>
>> (define-syntax identifier-name->string
>>    (lambda (stx)
>>  (syntax-case stx ()
>>    ((_ id)
>>     (identifier? #'id)
>>     (datum->syntax #'id (symbol->string (syntax->datum #'id)))
>>
>> ;; And the actual macro I want to write:
>>
>> (define-syntax define-api-route
>>    (lambda (stx)
>>  (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE
>> PATH)
>>    [(_ route GET my-content-type)
>>     (string-contains? (identifier-name->string (syntax route))
>> "abc")
>>     (println "abc is in the identifier name")])))
>> ~
>>
>> With this, Racket will complain, that I am referencing an identifier
>> before its definition:
>>
>> ~
>>  > (define-syntax id

[racket-users] Name of undefined identifier as string in macro

2019-08-03 Thread Zelphir Kaltstahl
Hi!

I am trying to write a macro, which checks the name of an argument for 
presence a substring. This is not the main purpose of the macro, but I want 
to do different things depending on the substring being contained or not 
contained.

Here is what I've got so far:

~
;; A macro to get the identifier name as string, shamelessly copied from 
StackOverflow and renamed:

(define-syntax identifier-name->string
  (lambda (stx)
(syntax-case stx ()
  ((_ id)
   (identifier? #'id)
   (datum->syntax #'id (symbol->string (syntax->datum #'id)))

;; And the actual macro I want to write:

(define-syntax define-api-route
  (lambda (stx)
(syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
  [(_ route GET my-content-type)
   (string-contains? (identifier-name->string (syntax route)) "abc")
   (println "abc is in the identifier name")])))
~

With this, Racket will complain, that I am referencing an identifier before 
its definition:

~
> (define-syntax identifier-name->string
(lambda (stx)
  (syntax-case stx ()
((_ id)
 (identifier? #'id)
 (datum->syntax #'id (symbol->string (syntax->datum #'id)))
> 
  (define-syntax define-api-route
(lambda (stx)
  (syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATH)
[(_ route GET my-content-type)
 (string-contains? (identifier-name->string (syntax route)) "abc")
 (println "abc is in the identifier name")])))
> (define-api-route abc/abc/abc GET 
application/json)   
  
; string-contains?: undefined;
;  cannot reference an identifier before its definition
;   in module: top-level
;   internal name: string-contains?
; [,bt for context]
~

If I take away the (syntax ...) in the guard expression however, it will 
also not work, as template variables may only occur in syntax:

~
> (define-syntax 
define-api-route
 
(lambda 
(stx)   

(syntax-case stx (GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE 
PATH)  [(_ route GET 
my-content-type)
 
(string-contains? (identifier-name->string route) 
"abc")  
(println "abc is in the identifier name")])))
; readline-input:19:52: route: pattern variable cannot be used outside of a
;   template
;   in: route
; [,bt for context]
~

I have also tried loads of other stuff, but I cannot find a way to:

1. get the identifier name of route, whatever the user has as route (not a 
string yet!)
2. check inside the guard expression, whether the identifier name contains 
a certain substring
3. based on that substring call other macros to do the actual job of 
defining an API route

Can you help me writing this macro?
It would also be great, if the macro was portable, meaning that it is 
usable from any Scheme.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/8b706c81-2587-4dc8--a900813571f1%40googlegroups.com.


[racket-users] Re: On Fire and Brimstone, Gnashing of Teeth, and the Death of All that is Holy

2019-07-24 Thread Zelphir Kaltstahl
Just for mentioning the original source: It has been made quite clear at 
RacketCon and the video recording of it, that #lang racket is here to stay 
with its current syntax.

My guess is still, that people are a bit worried about any syntax becoming 
second class citizen in Racket.

(btw.: I like the square brackets idea someone threw in at RacketCon (could 
not see who in the video) – simply genius :D)


On Tuesday, July 23, 2019 at 11:07:55 PM UTC, Michael Myers wrote:
>
> This is getting out of hand. There is a lot of misinformation swirling 
> around, sparking a lot of unnecessary panic and misunderstanding.
>
> Changing surface syntax, even for something as invasive as infix notation, 
> is not synonymous with abandoning s-expressions.
>
> Let me repeat this, for emphasis: changing the surface syntax, even to 
> introduce infix notation, does *NOT* require abandoning s-expressions.
>
> Let me assert a stronger point: even if, for the sake of calming people's 
> nerves, we were to make the following restrictions:
>
>1. Racket2 cannot use any reader other than the standard racket reader.
>2. Racket2 is not even allowed to be a #lang, the most it can do is be 
>an optional (require racket2) after #lang racket/base.
>
> ...we could still significantly alter racket's surface syntax, even to 
> introduce infix expressions.
>
> Now, which of the following are real s-expressions?
> x 
> (+ x y)
> (x + y)
> x 
> (+ x y)
> (x + y)
> 'x
> ('x ,y '(x y z) ('x'y'z)(x,y,z))
> (parse-sexpr '(f (x,y) = 2 x ^ 2 + 3 x - 4))
> (#%parse f (x,y) = 2 x ^ 2 + 3 x - 4)
> The answer, of course, is all of them.
>
> In fact, the last one is a macro I use fairly often, though I tend to give 
> it the shorter name $. 
> Consider the following: 
> https://github.com/mromyers/infix-syntax/blob/master/infix-syntax/test/core/base-test.rkt
>
> Now, consider the following possible programs:
>
> (def (abs x)(if (< x 0) (- x) x))
>
> def abs(x) = if x < 0 then - x else x
>
> def abs(x) = @(if (< x 0) (- x) x)
>
> (def (abs x)($ if x < 0 then - x else x))
>
> def sign(x) =
>   @(cond [($ x > 0)  'positive]
>  [($ x = 0)  'zero]
>  [($ x < 0)  'negative])
>
> If we treat $ as a macro that recursively parses its contents, and @ as a 
> unary operator that treats the expression to its right as a normal 
> s-expression, it is possible for all of the above to coexist with the 
> standard racket reader, with nothing more invasive than a redefined #%app 
> or #%module-begin.
>
> An 's-expression' does not have an inherent order of evaluation associated 
> with it. An 's-expression' does not have an inherent evaluation context, or 
> namespace, or semantics associated with it. What mflatt is proposing isn't 
> "abandoning s-expressions", it's just introducing some amount of parsing 
> and interleaving into the process of expansion, in a flexible and 
> extensible way, which doesn't even require modifying the expander in the 
> slightest. It doesn't inherently require changing the reader. It doesn't 
> inherently require changing anything about the syntax of fully-expanded 
> programs. It's likely that the reader would be tweaked a bit in the 
> process, but at the end of the day, 'read' will still turn strings into 
> s-expressions.
>
> If what you're worried about is that you won't be able to write programs 
> that look the way you want, you have nothing to fear. With this approach, 
> it is trivial to allow seamlessly switching between standard prefix style 
> lisp, and infix expressions, even in the exact same program. In Honu, the 
> equivalent of the @ operator above is a macro called racket_syntax. Now, 
> granted, it's not 100% automatic that switching and interop between these 
> will be painless and smooth. So the solution, if you're feeling scared, is 
> not to panic, but to stick around, and voice your preference for such 
> interoperability as a priority. Racket is a big tent, and so long as you're 
> friendly and willing to express your needs and constraints in a civil 
> manner, there's a lot of room to make something that appeals to many 
> different sensibilities.
>
> Lastly, if what you're worried about is that this somehow makes racket 'no 
> longer a true lisp', whatever that means, have no fear. The techniques Honu 
> uses are a development and refinement of techniques deeply tied to the 
> history of Lisp, originally implemented as a similar, but less 
> sophisticated reader macro for Maclisp. By sheer history it's lispier than 
> lexical binding! If that's not enough, and you have some reservation about 
> 'losing homoiconicity' or somerthing, I'd recommend reading the following: 
> http://calculist.org/blog/2012/04/17/homoiconicity-isnt-the-point/
>

-- 
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.
To view this 

[racket-users] Re: Racket2 possibilities

2019-07-22 Thread Zelphir Kaltstahl
I just want to give one thought as input to this discussion and will admit, 
that I did not read every (but some) of the posts above.

When I write code in Racket or Scheme, I mostly like the parentheses, as 
they make writing the code easy. I can very easily select a block and move 
it around, without introducing any syntax errors. I can also quickly see 
what the scope of something is, what other expression it is in. I don't get 
these things from languages without this many parentheses or without 
s-expression syntax. I need my parentheses as markers for my cursor to 
quickly jump around. It is the most pleasant code typing experience I've 
ever had. So when considering to move away from parentheses, please also 
consider the burden that those parentheses take away from the person 
writing the code. When I edit for example Python code, things are not clear 
when moving around code. This is worse in Python than in other languages, 
which at least have curly braces (but usually some other annoying 
deficiencies). If there was a move away from this many parentheses (read 
markers for my cursor), it would have to provide equal editability, for it 
to be attractive to me. A design based on indentation or something like 
that is not going to cut it for me. And what else would be used as start 
and end markers for expressions? Wouldn't that in essence just be another 
form of "parentheses", just looking different? How would any editor know, 
where an expression starts and ends for easy selection and moving around, 
if there were no such markers? So far I got no idea how that could be done 
without introducing loads of new constraints about how you can nest 
expressions into the language. So it beats me. Maybe my imagination in this 
area is still somewhat limited.

Just my 2c.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/bf0b5dd1-8802-4c78-af7a-4231ae30ad60%40googlegroups.com.


[racket-users] Re: Help with generators from python land!

2019-02-23 Thread Zelphir Kaltstahl
> The main difference, as has been pointed out before, is that Python
generators are more common as an idiom for solving problems that in
Racket would typically be approached differently.

This piqued my interest. Can you elaborate a bit or give an example? How
would one approach things with Racket differently?

I imagine some input, that is too big and should be handled one element
at a time instead. How would one do that in Racket, when not using
something comparable to a Python generator?

-- 
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] Help with generators from python land!

2019-02-21 Thread Zelphir Kaltstahl
Ah, you are of course right. Somehow I thought about `for/list` and
returning lists and then doing something on the returned list, instead
of simply doing it _inside_ the `for`. Apologies!

On 2/21/19 8:46 PM, Robby Findler wrote:
> For the record, `for` iterators go element-by-element. For example,
> this program does not construct anything that has all of the natural
> numbers in it:
>
> #lang racket
>
> (define my-stuffs-value
>   (hash 'telephone 3
> 'bluejeans 24
> 'house 10
> 'computer 3000))
>
> (define my-estates-value
>   (for/sum ([i (in-naturals)]
> [(k v) (in-hash my-stuffs-value)])
> (printf "item ~a is worth ~a\n" i v)
> v))
>
> my-estates-value
>
> On Thu, Feb 21, 2019 at 1:40 PM Zelphir Kaltstahl
>  wrote:
>> I don't think one can see `for` in Racket as equivalent to generators in 
>> Python.
>>
>> Generators in Python are used when you want to save memory by not producing 
>> all values at once, but want to go value by value (which to my knowledge 
>> Racket's `for` variants do not do, but I'd like to be corrected, if I am 
>> wrong about this, as it would mean, that those `for` are even more awesome 
>> than I knew.) They are more like lazy possibly infinite lists. I think lazy 
>> Racket has that and that there was some advice about not calling `length` on 
>> an infinite list.
>>
>> Python, I believe, has some kind of `Iterable` interface, which a generator 
>> satisfies and which specifies the method to call to get the next value. In 
>> Racket maybe one would have to do with a convention of how to get a next 
>> value from a lazy list.
>>
>> I believe something like the following could be an example. I did not yet 
>> think about macros, nor am I experienced with that, so maybe one can create 
>> something more elegant than what I am posting:
>>
>> ~~~
>> #lang racket
>>
>> ;; 
>> ;; DATA ABSTRACTION
>> ;; 
>>
>> ;; The value is always the first value of the generator.
>> (define get-value car)
>>
>> ;; A generator's producing procedure needs to be applied to get the
>> ;; next thing.
>> (define (get-next a-gen)
>>   ((cdr a-gen)))
>>
>> ;; A generator is only a tuple containing the current value and the
>> ;; procedure to create the next value
>> (define (make-gen proc start)
>>   (cons start
>> (lambda ()
>>   (make-gen proc (proc start)
>>
>> (define STOP-SYMBOL 'none)
>>
>> ;; 
>> ;; EXAMPLES
>> ;; 
>>
>> ;; An infinite list of numbers.
>> (define natural-numbers
>>   (make-gen (lambda (x) (+ x 1))
>> 0))
>>
>> ;; A limited list of natural numbers.
>> (define (limited-natural-numbers limit)
>>   (make-gen (lambda (x)
>>   (cond [(< x limit) (+ x 1)]
>> [else STOP-SYMBOL]))
>> 0))
>>
>> ;; Print a certain amount of natural numbers.
>> (define (print-natural-numbers natural-numbers limit)
>>   (let ([current-number (get-value natural-numbers)])
>> (cond
>>   [(and (symbol? current-number) (symbol=? current-number STOP-SYMBOL))
>>(displayln "No more numbers available!")]
>>   [(< current-number limit)
>>(displayln current-number)
>>(print-natural-numbers (get-next natural-numbers) limit)]
>>   [else
>>(displayln "Done")])))
>> ~~~
>>
>> Here the conventions are the structure of the generator and the stop symbol. 
>> In Python those are already taken care of by the standard library's 
>> generator interface.
>>
>>
>> On Wednesday, February 20, 2019 at 10:10:16 PM UTC, Jens Axel Søgaard wrote:
>>> Den ons. 20. feb. 2019 kl. 22.25 skrev Dave McDaniel :
>>>> Hello,
>>>>
>>>> I have interest in picking up racket and have done some koans and also 
>>>> have been doing the racket track on exercism.
>>>>
>>>> There is a fairly simple exercise called `etl` on exercism related to 
>>>> taking a hash for scoring scrabble letters and unpacking it into a 
>>>> flatter, more efficient structure for lookups.
>>>>
>>>> The input hash has score as the key and a list of letters of that score as 
>>>> the value.  The output is a hash of letter -> score.  One pair per letter 
>>>> instead of one pair per score.
>>>>
>>>> It was easy enough

[racket-users] Re: How do you make students submit programming assignments online for automatic tests?

2019-02-21 Thread Zelphir Kaltstahl
If you were using Racket, you might be interested in this RacketCon video 
(time is linked):

https://youtu.be/WI8uA4KjQJk?t=1510

Racket has a very tree like code structure right in front of the developer, 
while I guess you would have to get through to the AST in other languages, 
where that is not the case, to do something similar. I found that project 
quite impressive and I wish I had something like it for other languages. I 
think there is also a paper about it. You can find it by searching for the 
name of the speaker.

On Wednesday, February 20, 2019 at 5:51:38 PM UTC, Marc Kaufmann wrote:
>
> Hi all,
>
> I will be teaching a course on data analysis in R next year (September), 
> and may at some point add some Racketeering to my other courses (maybe), 
> and I was wondering how those of you who teach programming classes deal 
> with programming assignments. Are there somewhat language-independent 
> platforms for having students submit assignments that have to pass a bunch 
> of pre-specified tests, or would I need to look at what is available for 
> any given platform? Any security issues I should be aware of?
>
> All recommendations welcome,
>
> Marc
>

-- 
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] Help with generators from python land!

2019-02-21 Thread Zelphir Kaltstahl
I don't think one can see `for` in Racket as equivalent to generators in 
Python.

Generators in Python are used when you want to save memory by not producing 
all values at once, but want to go value by value (which to my knowledge 
Racket's `for` variants do not do, but I'd like to be corrected, if I am 
wrong about this, as it would mean, that those `for` are even more awesome 
than I knew.) They are more like lazy possibly infinite lists. I think lazy 
Racket has that and that there was some advice about not calling `length` 
on an infinite list.

Python, I believe, has some kind of `Iterable` interface, which a generator 
satisfies and which specifies the method to call to get the next value. In 
Racket maybe one would have to do with a convention of how to get a next 
value from a lazy list.

I believe something like the following could be an example. I did not yet 
think about macros, nor am I experienced with that, so maybe one can create 
something more elegant than what I am posting:

~~~
#lang racket

;; 
;; DATA ABSTRACTION
;; 

;; The value is always the first value of the generator.
(define get-value car)

;; A generator's producing procedure needs to be applied to get the
;; next thing.
(define (get-next a-gen)
  ((cdr a-gen)))

;; A generator is only a tuple containing the current value and the
;; procedure to create the next value
(define (make-gen proc start)
  (cons start
(lambda ()
  (make-gen proc (proc start)

(define STOP-SYMBOL 'none)

;; 
;; EXAMPLES
;; 

;; An infinite list of numbers.
(define natural-numbers
  (make-gen (lambda (x) (+ x 1))
0))

;; A limited list of natural numbers.
(define (limited-natural-numbers limit)
  (make-gen (lambda (x)
  (cond [(< x limit) (+ x 1)]
[else STOP-SYMBOL]))
0))

;; Print a certain amount of natural numbers.
(define (print-natural-numbers natural-numbers limit)
  (let ([current-number (get-value natural-numbers)])
(cond
  [(and (symbol? current-number) (symbol=? current-number STOP-SYMBOL))
   (displayln "No more numbers available!")]
  [(< current-number limit)
   (displayln current-number)
   (print-natural-numbers (get-next natural-numbers) limit)]
  [else
   (displayln "Done")])))
~~~

Here the conventions are the structure of the generator and the stop 
symbol. In Python those are already taken care of by the standard library's 
generator interface.


On Wednesday, February 20, 2019 at 10:10:16 PM UTC, Jens Axel Søgaard wrote:
>
> Den ons. 20. feb. 2019 kl. 22.25 skrev Dave McDaniel  >:
>
>> Hello,
>>
>> I have interest in picking up racket and have done some koans and also 
>> have been doing the racket track on exercism.
>>
>> There is a fairly simple exercise called `etl` on exercism related to 
>> taking a hash for scoring scrabble letters and unpacking it into a flatter, 
>> more efficient structure for lookups.
>>
>> The input hash has score as the key and a list of letters of that score 
>> as the value.  The output is a hash of letter -> score.  One pair per 
>> letter instead of one pair per score.
>>
>> It was easy enough to solve with `for-each` using side-effects to update 
>> a mutable hash, however I think using a generator is a cleaner approach and 
>> doesn't require mutability.  
>>
>
> FWIW here is a solution using immutable hashes. I see `for` and friends as 
> Racket "generators". 
>
> /Jens Axel
>
>
> #lang racket
> (require racket/hash)
>
> ; In Scrabble each letter gives a certain number of points.
> ; In the old data we have for each point a list of numbers,
> ; that awarded the given number of points.
>
> (define old-data
>   ; list of associations from point to list of strings (letters)
>   '((1  "A" "E" "I" "O" "U" "L" "N" "R" "S" "T")
> (2  "D" "G")
> (3  "B" "C" "M" "P")
> (4  "F" "H" "V" "W" "Y")
> (5  "K")
> (8  "J" "X")
> (10 "Q" "Z")))
>
>
> ; Each point list needs to be transformed to a
> ; hash table from letters to points.
>
> (define (transform association)
>   (match association
> [(list point letters ...)
>  (for/hash ([letter letters])
>(values (string-downcase letter) point))]))
>
> ; Now we only need to combine the hash lists.
> (define ht
>   (apply hash-union
>(hash)
>(for/list ([association old-data])
>  (transform association
>
> (define (lookup letter)
>   (hash-ref ht letter #f))
>
> (lookup "e")
> (lookup "x")
>
>
>
>

-- 
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] Re: Python's append vs Racket's append and helping novices understand the implications

2019-02-03 Thread Zelphir Kaltstahl
I think having such migration pages for people coming from other
languages is a good idea. Maybe also should include basic programming
knowledge such as "a single linked list is not a vector", but then where
to begin? If such page says that some operations are slower on Racket
lists (append), then best to put also an explanation why this is not
necessarily a bad thing (because the lists are used in a certain way,
where such operations are avoided mostly and otherwise we use
differently named data structures) or in what situations some operations
are faster. Otherwise people might simply go and think: "Oh my, why
don't they simply use lists like in Python?" The page needs to tell
people: "What you found in Python, you also have in Racket, just use
data structure xyz."


-- 
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] Re: Serving my web application and some static files

2019-02-01 Thread Zelphir Kaltstahl
I am not sure if anything in this 
https://github.com/ZelphirKaltstahl/racket-markdown-blog/blob/master/blog/server.rkt#L51
 
helps you.

On Wednesday, January 30, 2019 at 4:42:57 PM UTC, cwebber wrote:
>
> It seems like it should be so simple, and like Racket has the tools 
> already, but I can't figure out how to do it. 
>
> I have the following: 
>
>   (serve/servlet start 
>  #:servlet-regexp #rx"" 
>  #:launch-browser? #f) 
>
> I'd like to do something like the following: 
>
>   - Serve static files for urls matching /static/* 
>   - Serve those very files from the ./static/ directory 
>
> I'd expect I'd do something like combine that all with: 
>
>   (file-dispatch:make #:url->path (make-url->path 
> (build-path cwd "static"))) 
>
> But I'm lost.  I can figure out how to serve static files OR use the 
> controllers in my start function, but combining them???  I'd like to 
> serve some static files *in addition* to my the above code.  Between 
> dispatchers and servlets and even the file serving dispatchers, I 
> thought I could figure out something relatively easy out of the box. 
> But hours later I'm still scratching my head about how to combine 
> servlets or dispatchers or what have you. 
>
> I've read a bunch of things: 
>  - https://www.greghendershott.com/2013/03/serve-static-files.html 
>  - https://docs.racket-lang.org/web-server-internal/dispatch-files.html 
>  - 
> https://docs.racket-lang.org/web-server-internal/dispatch-sequencer.html 
>  - and pretty much everything under 
> https://docs.racket-lang.org/web-server/ 
>
> ... but I can't figure out how to do it without reinventing all the 
> machinery that appears to already exist in Racket.  There must be 
> something obvious and simple right in front of me. 
>

-- 
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] Re: Beginning of the end for googlegroups?

2019-01-26 Thread Zelphir Kaltstahl
I've always wondered, why Racket uses Google groups and guesses, that it
is because of low setup effort required. In such cases the darker side
of lock in system shows: Not so easy to get away from them. When the
lights go out it is possible to lose everything. It's very similar to
the effect some wiki systems have (for example confluence wiki), where
you have no good "export everything on this page" option. The most
natural export formats not available etc. Personally I'd be all for
something independent from Google or big companies.

Of course it might be a lot of work without proper export ways.

-- 
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] Are the terms "function" and "procedure" synonymous in Racket?

2019-01-22 Thread Zelphir Kaltstahl


On 1/23/19 12:32 AM, Hendrik Boom wrote:
> On Tue, Jan 22, 2019 at 01:52:15AM -0500, George Neuner wrote:
>
>> I am arguing that, in computing, functions and procedures have no
>> significant difference, and that distinguishing them erroneously conflates
>> computing with mathematics and thus confuses people.
> The distinction I've heard from people that care abut these things and that
> seems to make sense are fo divide these subrutines into
>
> * procedures
>   * do things, have side effects
> * Value-returning procedures
>   * procedures that happen to return values
> * functions
>   * that return values and have no side effects (or side dependencies?)
>
> But it hasn't been very practical to make these distinctions in computer
> programs, because there is no effective way to distinguish such 
> functions from value-returning proedures.
>
> The restriction that functions can use only other functions doesn't 
> really work because
>   * Too many things that behave like functions use side-effects 
> internally while returning values that depend only on their arguments.
>   * Applied strictly, it rules out memo pads.
>
> The distinction, if it could be practically enforced, would give 
> optimisers significant opportunity for program tranformation.
>
> -- hendrik
>
I think this is a vocabulary and definitions question. It is very useful
to be able to talk about these things and distinguish between them. For
example, one could demand a side effect free thing to be able to easily
write unit tests later on for that thing. Many parts of a program can
consist of side effect free things, before at some point there will be
side effects. Might be the only side effects are putting something out
on command line and the whole rest is always only depending on arguments
and never accessing anything global or outside of the scope. Also side
effect free parts can be distinguished in natural language, by the way
we talk about them and tested separately and more easily. Someone new to
the field will hopefully ask what the differences are and will learn
then and then be able to talk precisely about it as well.

This is a reason why I personally think making the distinction is
useful, even if you cannot have the side effect free stuff all the way
through every part of a useful usable program. Communication is an
important part, not only writing the code.

The definition you gave of the categories of subroutines is what I heard
/ read / saw as well.

-- 
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] Are the terms "function" and "procedure" synonymous in Racket?

2019-01-22 Thread Zelphir Kaltstahl
On 1/22/19 11:08 PM, George Neuner wrote:
>
> On 1/22/2019 2:31 PM, Zelphir Kaltstahl wrote:
>> If the terms procedures and functions in computing have no
>> significant difference, then why use two terms for the same thing, of
>> which one is already used in mathematics, enabling confusion to appear?
>>
>> This would make a fine argument for not using the word "function" for
>> computing at all and keep to using the term "procedure" all the way.
>
> That's what many older languages did - Fortran and Lisp being notable
> exceptions, but they can be forgiven because they were the first
> (abstraction able) programming languages, and their early users were
> people who knew and understood the difference between computing and
> mathematics. 
>
> In the world of syntax design, wholesale use of the term "function" -
> *relatively* - is a new thing.


Hmmm. In general I have to say, I tend to "vote" for using the terms,
that are most precise, even if people do not understand, in hope of
making them wonder and maybe ask themselves, why someone would use that
term instead of another: "Why are they talking about procedures all the
time, instead of functions? Is there a difference?" and then maybe they
will find out or ask. Also to not contribute to making people think it
is the same as mathematical functions.
I think using the term "function" rather hides that and does not inspire
thinking about it. For example the recorded SICP lecture also made me
more conscious about my usage of the word "function". So did some other
FP articles and language tutorials.
I ask myself: Shouldn't we strive to understand just as much as people
before us, even if that means getting used to using their terminology,
since they knew what they were talking about?


>> I disagree on one more point. It is not necessary to always remember
>> the low level character of code running on a machine, if the language
>> we are using abstracts it well and guarantees us, that there will not
>> be strange effects in all the relevant cases for our programs.
>
> But a language CAN'T guarantee that there will not be effects -
> "strange" or otherwise.  Spectre attacks work even against code that
> is correct WRT its programming language because languages either are
> ignorant of - or are intentionally ignoring - side effects of those
> fiddly little machine operations.


That is a connection I do not fully understand. Spectre attack is
something designed to break the system, or out of previously known
bounds of what some code could do. Can such a thing happen
unintentionally, when we write useful / constructive / productive / well
meaning programs? I guess theoretically, but very very unlikely?

I get that there is a chance of something having a strange effect, when
the CPU is this kind of buggy (Intel cutting corners, still waiting for
my free of charge sent replacement CPU, free from such bugs, being
inserted in my machines for me by Intel :D), but that problem is on a
lower layer of abstraction. If the language we use is in itself correct,
isn't it then up to the lower layers to get things right? Afaik Spectre
(or was that Meltdown?) are only possible, because of over optimistic
branch prediction stuff (not an expert on such low level details at all,
just from what I read online). Couldn't we construct hardware free of
such mistakes? Or is there something fundamental, that will not allow
that, so that we cannot ever have a language guaranteeing things?


>> What I am relating to is:
>>
>> > The computer abstraction of "applying a function" can only be
>> stretched
>> > so far.  Those fiddly little "steps" that approximate the function
>> can't
>> > legitimately be ignored: they consumed time and energy, and [barring
>> > bugs] in the end they gave you only an approximation - not an answer
>>
>> Yes it can only be stretched that far (not infinite resources,
>> precision etc.), however, there are many situations, where I think
>> the stepwise nature can be legitimately ignored. I would say, if a
>> language is well designed and the interpreter / compiler and things
>> in between that run it are proven to be correct, I do not see, why we
>> should not ignore the stepwise nature of code execution. Why would it
>> be useful to look at that, provided our program is sufficiently
>> performant and does what we want? Furthermore they often do give me
>> an answer. It may not always be the case for numbers, because of
>> precision and such things, but think of things like joining together
>> some strings, some constructs well defined in the language we use and
>> the result of such procedure call would be an answer an

Re: [racket-users] Are the terms "function" and "procedure" synonymous in Racket?

2019-01-22 Thread Zelphir Kaltstahl
If the terms procedures and functions in computing have no significant 
difference, then why use two terms for the same thing, of which one is 
already used in mathematics, enabling confusion to appear?

This would make a fine argument for not using the word "function" for 
computing at all and keep to using the term "procedure" all the way. This 
is also btw. what I take from the recorded videos of SICP lectures 
(https://www.youtube.com/watch?v=2Op3QLzMgSY=PL8FE88AA54363BC46). 
Somewhere in the first lectures Abelson or Sussman state, that a "function" 
is a term used in mathematics and then he goes over to immediately talking 
about procedures instead. To me this makes perfect sense and makes a point 
of distinguishing between the two things, without introducing the word 
function into our programming or computing vocabulary.

I disagree on one more point. It is not necessary to always remember the 
low level character of code running on a machine, if the language we are 
using abstracts it well and guarantees us, that there will not be strange 
effects in all the relevant cases for our programs. What I am relating to 
is:

> The computer abstraction of "applying a function" can only be stretched 
> so far.  Those fiddly little "steps" that approximate the function can't 
> legitimately be ignored: they consumed time and energy, and [barring 
> bugs] in the end they gave you only an approximation - not an answer

Yes it can only be stretched that far (not infinite resources, precision 
etc.), however, there are many situations, where I think the stepwise 
nature can be legitimately ignored. I would say, if a language is well 
designed and the interpreter / compiler and things in between that run it 
are proven to be correct, I do not see, why we should not ignore the 
stepwise nature of code execution. Why would it be useful to look at that, 
provided our program is sufficiently performant and does what we want? 
Furthermore they often do give me an answer. It may not always be the case 
for numbers, because of precision and such things, but think of things like 
joining together some strings, some constructs well defined in the language 
we use and the result of such procedure call would be an answer and not 
only an approximation.

I don't think it's a good idea to conflate the meaning of "function", from 
my current level of experience at least ;)

On Tuesday, January 22, 2019 at 6:52:22 AM UTC, gneuner2 wrote:
>
>
> On 1/21/2019 11:52 PM, Anthony Carrico wrote: 
> > On 1/18/19 6:36 PM, George Neuner wrote: 
> > > Historically, many computer language designers were mathematicians, 
> and 
> > > they deliberately sought to distinguish "computer" functions from 
> > > "mathematical" functions. 
> > > 
> > > It has yet to work completely - witness the legions of newbies every 
> > > year who don't understand that computer arithmetic differs from the 
> math 
> > > they were taught in school. 
> > 
> > 
> > George: Aren't you making my case here? The mathematicians actually have 
> > the same trouble with their components as we engineers! Stoy says, "a 
> > careful distinction is vital in the case of functions", admonishing us 
> > not to "confuse functions with the algorithms representing them." 
> > Weren't Schemers making this distinction with the word "procedure"? 
>
> You and I may, in fact, agree on the basis - but I don't believe we are 
> arguing the same things. 
>
> If I understand correctly, you are arguing that computing should 
> distinguish functions from procedures because functions have a 
> connection [however tenuous] to mathematics that procedures do not. 
>
> I am arguing that, in computing, functions and procedures have no 
> significant difference, and that distinguishing them erroneously 
> conflates computing with mathematics and thus confuses people. 
>
>
> You began by saying: 
> >> However, for practical reasons, the programming community is now 
> >> placing more emphasis on the distinction between functional and 
> >> procedural abstraction, so I'm very surprised to see the Racket 
> >> community rally to eliminate it. Even within the same abstraction 
> >> mechanism, the two ideas are very useful. 
>
> The problem I see is that the ideas AREN'T separate. 
>
> Somewhere upward in this thread I wrote [not necessarily to you, 
> Anthony] that mathematical functions simply are, whereas their 
> corresponding computer "functions" are a series of steps that, at best, 
> can only approximate the result of the mathematical version. 
>
> There is no "series of steps" distinction between a computer function 
> and procedure - they both are a series of steps. 
>
> The computer abstraction of "applying a function" can only be stretched 
> so far.  Those fiddly little "steps" that approximate the function can't 
> legitimately be ignored: they consumed time and energy, and [barring 
> bugs] in the end they gave you only an approximation - not an answer. 
>
> For computing, "function" vs 

[racket-users] Re: Are contracts incompatible with Typed Racket?

2018-12-16 Thread Zelphir Kaltstahl
As far as I know contracts in Racket are evaluated at run time, for
example when calling a procedure from another module and the module has
a contract for the procedure, while types of typed Racket are evaluated
at read time. They seem to be independent concepts. I am not sure how to
use both of them in the same project. However, I remember, that I also
tried to use contracts additionally when using typed Racket once or
twice and ended up having only contracts, because of some problem. What
I do remember is, that I had some typed Racket type inference problems,
when I had some kind of nested for loops. It might be, that this is, why
I ended up using only contracts and it might have been a solvable
problem, had I saved that code and asked here on the mailing list.

> I recently started learning Racket and quickly switched to Typed
Racket. For the most part I've been very happy with it, but I'm unclear
on whether it's possible to create contracts in Typed Racket (for
expressing constraints other than type requirements). I've been unable
to find an explicit answer to my question in the docs for either
contracts or Typed Racket, but I've run several experiments and it seems
that contracts are incompatible with Typed Racket. This discussion

 seems
to support my conclusion.

> If you can't create your own contracts in Typed Racket, are you meant
to limit all of your contract-related needs to type requirements? Or
just use vanilla Racket if you need a full-fledged contract system?
Additionally, could someone point me to the documentation that would
have answered by question (if it exists)?

> Thanks!

-- 
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] Re: Goblins, and actor model library for Racket, gets its first release

2018-10-29 Thread Zelphir Kaltstahl

I have not tried the Goblins library yet, but it sounds great! 
Also kudos for doing the free software thing! I hope you can keep it up and 
that many people support you in the free software endeavors. 

On Sunday, October 28, 2018 at 5:10:18 PM UTC+1, cwebber wrote:
>
> Hello all, 
>
> I've made the first release of Goblins (v0.1), the lightweight actor 
> model I'm building for Racket which will be the foundation for my future 
> distributed virtual worlds work in Racket.  It is *not* production 
> ready, consider this a pre-alpha, but you can get it from Racket's 
> package repository, and read the docs here: 
>
>   https://docs.racket-lang.org/goblins/ 
>
> I think the docs give a pretty nice overview of what using Goblins 
> should "feel" like. 
>
> The long term goal of Goblins is to bring secure, distributed object 
> capability computation to Racket, inspired largely by the E programming 
> language (Goblins borrows many of its good ideas, including the promise 
> pipelining features).  It doesn't do distributed computation yet, but 
> I'm hoping to roll that out in the next couple of months. 
>
> Be aware that there are bugs.  In particular, I've hit some interesting 
> bugs involving delimited continuations: 
>   https://gitlab.com/spritely/goblins/issues/8 
> (I think I may be poking at some interesting internals of Racket in the 
> ways I'm pushing delimited continuations to their limits... recently I 
> even managed to segfault the GC.  I'll follow up on that stuff on the 
> other thread I started recently shortly.) 
>
> Anyway, I think it's an exciting foundation.  I'd love to hear feedback. 
>
>  - Chris 
>
> If you are curious about what this long term plan about building secure 
> virtual worlds in Racket is, I wrote a blogpost named "Spritely: towards 
> secure social spaces as virtual worlds": 
>   https://dustycloud.org/blog/spritely/ 
>
> I have recently switched to working on this full time.  I don't have a 
> funding plan yet, but I am committed to make sure that the Spritely 
> project as a whole is a public good.  If you think this work is 
> exciting, consider supporting my work: 
>   https://www.patreon.com/cwebber 
>

-- 
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] Re: Please HELP ME! Programmers at scheme, i am calling you ! :D

2018-05-12 Thread Zelphir Kaltstahl
Maybe I misunderstand, but doesn't
https://docs.racket-lang.org/reference/mpairs.html already solve this?

Unless it is a purely educational exercise of how to implement such a
thing of course.


-- 
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] Re: Jupyter Racket Kernel - iracket

2018-05-01 Thread Zelphir Kaltstahl
Ah great to hear that!
At work I deal a lot with the Jupyter ecosystem and I think it has an 
interesting future. It is good for Racket to be available there. I 
personally have not used it so much for diagrams and visual things, but 
maybe some day it will have some similar integration as Jupyter has with 
the Python ecosystem and its libraries. Or maybe there will be another 
language build with Racket for that purpose.

On Monday, April 30, 2018 at 9:28:41 PM UTC+2, Graham Dean wrote:
>
>
> I’ve been looking to use Racket in a Jupyter notebook and I came across 
> Ryan Culpepper’s iracket (https://github.com/rmculpepper/iracket). 
>
> Unfortunately, it doesn’t work with the latest Jupyter system due to a new 
> client message (comm_info_request) that isn’t handled. 
>
> I’ve made some very simply changes that get iracket working again in 
> Jupyter and just in case it’s useful for anyone else it can be found at 
> https://github.com/digsci/iracket. 
>
> I should really make a pull request (or at least an issue report to the 
> original I guess. 
>
> Graham 

-- 
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] Regexp question matching a whole string

2018-04-27 Thread Zelphir Kaltstahl
Yep, that works, thank you.
I did not know that EOF alone could be there.

On Monday, April 23, 2018 at 2:16:52 AM UTC+2, Sam Tobin-Hochstadt wrote:
>
> Typed Racket is reminding you that `read-line` can produce EOF. If you 
> handle that (for example, with `(assert something string?)`) then it 
> works correctly. 
>
> Sam 
>
> On Sun, Apr 22, 2018 at 4:40 PM, Zelphir Kaltstahl 
> <zelphirk...@gmail.com > wrote: 
> > Ah OK, I understand that additional newline. Since the code matching the 
> > regex is run before that newline gets in, the newline will be on the 
> > input port. 
> > 
> > In DrRacket I observe the following: 
> > 
> > (I remembered that there are negative numbers :D and my regex got a bit 
> > more complicated.) 
> > 
> > ~~~ 
> > (regexp-try-match #rx"\\s*^(-?[1-9]+[0-9]*)$|\\s*^0$" 
> (current-input-port)) 
> > ~~~ 
> > 
> > When I run it the first time, I get the "input box" where I can click 
> > the "EOF" button on the right and the regex seems to work. When I try 
> > again immediately after, the first time, there is still an # on the 
> > port, which apparently was not consumed, so it will immediately return 
> > #f. I can get rid of that # by running (read-line) once. On REPL 
> > line I would have a newline and in DrRacket I have an #. 
> > 
> > On REPL it does not stop expecting input, because it never receives an 
> > #. I read somewhere on Stackoverflow that I input # by 
> > pressing Ctrl+d and that may be true, but it does not work in REPL, 
> > because that shuts down the REPL. So basically it seems impossible to 
> > test such regular expressions on REPL. 
> > 
> > I think I will instead use: 
> > 
> > ~~~ 
> > (let ([something (read-line (current-input-port) 'any)]) 
> >   (... do regex things on finished string here ...)) 
> > ~~~ 
> > 
> > to work around this problem in the future. This will actually finish the 
> > line at any marker of a new line and then let me work with the regex 
> > more comfortably. Also instead of running it in the REPL, I will 
> > probably run a small program instead with racket . 
> > 
> > Thanks for clearing up my confusion! 
> > 
> > I tried to write this in Typed Racket and the following is what I got. 
> > This works: 
> > 
> > ~~~ 
> > (: get-input-number (-> Integer)) 
> > (define (get-input-number) 
> >   (let loop : Integer () 
> > (let ([something (read-line (current-input-port) 'any)]) 
> >   (cond [(string? something) 
> >  (let ([number-representation (string->number something)]) 
> >(cond [(exact-integer? number-representation) 
> number-representation] 
> >  [else (printf "nope~n") 
> >(loop)]))] 
> > [else (printf "nope~n") 
> >   (loop)] 
> > 
> > (get-input-number) 
> > ~~~ 
> > 
> > While the following does not work: 
> > 
> > ~~~ 
> > (define (get-input-number-2) 
> >   (let loop : Integer () 
> > (let* ([something (read-line (current-input-port) 'any)] 
> >[match-res (regexp-match #rx"(^-?[1-9]+[0-9]*$)|(^0$)" 
> something)]) 
> >   (cond [(string? something) 
> >  (let ([number-representation (string->number something)]) 
> >(cond [(exact-integer? number-representation) 
> number-representation] 
> >  [else (printf "nope~n") 
> >(loop)]))] 
> > [else (printf "nope~n") 
> >   (loop)] 
> > 
> > (get-input-number-2) 
> > ~~~ 
> > 
> > The opening paren of regexp-match is underlined and when I run this code 
> > I get the lengthy error message: 
> > 
> > ~~~ 
> > main.rkt:34:22: Type Checker: No function domains matched in function 
> > application: 
> > Domains: (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) 
> > Integer (U False Integer) (U False Output-Port) Bytes #f * 
> >  (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) 
> > Integer (U False Integer) (U False Output-Port) #f * 
> >  (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) 
> > Integer (U False Integer) #f * 
> >  (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) 
> > Integer #f * 
> >  (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) #f * 
> >  (U Byte-Re

Re: [racket-users] Regexp question matching a whole string

2018-04-27 Thread Zelphir Kaltstahl
That is an interesting and probably much better way to do it.
Of course I did remember -0/42 … *clears throat* (not) :D

Thank you!

On Monday, April 23, 2018 at 12:03:38 AM UTC+2, Matthew Butterick wrote:
>
> On Apr 22, 2018, at 1:40 PM, Zelphir Kaltstahl <zelphirk...@gmail.com 
> > wrote:
>
> Ah OK, I understand that additional newline. Since the code matching the
> regex is run before that newline gets in, the newline will be on the
> input port.
>
> In DrRacket I observe the following:
>
> (I remembered that there are negative numbers :D and my regex got a bit
> more complicated.)
>
>
> Parsing numbers with regex is prone to error, because you'll often miss 
> edge cases. For instance, did you remember that -0/42 is an exact integer?
>
> A nice way to avoid these headaches is to delegate the heavy lifting to 
> `read`, and then just test the result value:
>
> #lang racket
> (for/first ([val (in-port read)]
> #:when (exact-integer? val))
>val) 
>
>

-- 
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] Regexp question matching a whole string

2018-04-22 Thread Zelphir Kaltstahl
Ah OK, I understand that additional newline. Since the code matching the
regex is run before that newline gets in, the newline will be on the
input port.

In DrRacket I observe the following:

(I remembered that there are negative numbers :D and my regex got a bit
more complicated.)

~~~
(regexp-try-match #rx"\\s*^(-?[1-9]+[0-9]*)$|\\s*^0$" (current-input-port))
~~~

When I run it the first time, I get the "input box" where I can click
the "EOF" button on the right and the regex seems to work. When I try
again immediately after, the first time, there is still an # on the
port, which apparently was not consumed, so it will immediately return
#f. I can get rid of that # by running (read-line) once. On REPL
line I would have a newline and in DrRacket I have an #.

On REPL it does not stop expecting input, because it never receives an
#. I read somewhere on Stackoverflow that I input # by
pressing Ctrl+d and that may be true, but it does not work in REPL,
because that shuts down the REPL. So basically it seems impossible to
test such regular expressions on REPL.

I think I will instead use:

~~~
(let ([something (read-line (current-input-port) 'any)])
  (... do regex things on finished string here ...))
~~~

to work around this problem in the future. This will actually finish the
line at any marker of a new line and then let me work with the regex
more comfortably. Also instead of running it in the REPL, I will
probably run a small program instead with racket .

Thanks for clearing up my confusion!

I tried to write this in Typed Racket and the following is what I got.
This works:

~~~
(: get-input-number (-> Integer))
(define (get-input-number)
  (let loop : Integer ()
    (let ([something (read-line (current-input-port) 'any)])
  (cond [(string? something)
 (let ([number-representation (string->number something)])
   (cond [(exact-integer? number-representation) 
number-representation]
 [else (printf "nope~n")
   (loop)]))]
    [else (printf "nope~n")
  (loop)]

(get-input-number)
~~~

While the following does not work:

~~~
(define (get-input-number-2)
  (let loop : Integer ()
    (let* ([something (read-line (current-input-port) 'any)]
   [match-res (regexp-match #rx"(^-?[1-9]+[0-9]*$)|(^0$)" something)])
  (cond [(string? something)
 (let ([number-representation (string->number something)])
   (cond [(exact-integer? number-representation) 
number-representation]
 [else (printf "nope~n")
   (loop)]))]
    [else (printf "nope~n")
  (loop)]

(get-input-number-2)
~~~

The opening paren of regexp-match is underlined and when I run this code
I get the lengthy error message:

~~~
main.rkt:34:22: Type Checker: No function domains matched in function
application:
Domains: (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port)
Integer (U False Integer) (U False Output-Port) Bytes #f *
 (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port)
Integer (U False Integer) (U False Output-Port) #f *
 (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port)
Integer (U False Integer) #f *
 (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port)
Integer #f *
 (U Byte-Regexp Bytes Regexp String) (U Bytes Input-Port) #f *
 (U Byte-Regexp Bytes) (U Bytes Input-Port Path-String) Integer
(U False Integer) (U False Output-Port) Bytes #f *
 (U Byte-Regexp Bytes) (U Bytes Input-Port Path-String) Integer
(U False Integer) (U False Output-Port) #f *
 (U Byte-Regexp Bytes) (U Bytes Input-Port Path-String) Integer
(U False Integer) #f *
 (U Byte-Regexp Bytes) (U Bytes Input-Port Path-String) Integer #f *
 (U Byte-Regexp Bytes) (U Bytes Input-Port Path-String) #f *
 (U Regexp String) Path-String Integer (U False Integer) (U
False Output-Port) Bytes #f *
 (U Regexp String) Path-String Integer (U False Integer)
  context...:
  
/usr/share/racket/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:345:0:
type-check
  
/usr/share/racket/pkgs/typed-racket-lib/typed-racket/typecheck/tc-toplevel.rkt:588:0:
tc-module
  
/usr/share/racket/pkgs/typed-racket-lib/typed-racket/tc-setup.rkt:94:0:
tc-module/full
  
/usr/share/racket/pkgs/typed-racket-lib/typed-racket/typed-racket.rkt:23:4
   standard-module-name-resolver
~~~

(Racket 6.10.1)

I am aware, that I do not really need the match-res, but this is only
some trying out of stuff. I am not really sure what it expects me to do
about the regexp-match. It seems it must be used differently in TR.
Should I put this in a new question ("How to use regexp-match in TR?")
instead?


On 22.04.2018 15:15, Matthew Flatt wrote:
> At Sun, 22 Apr 2018 14:54:26 +0200, Zelphir Kaltstahl wrote:
>> I

Re: [racket-users] Regexp question matching a whole string

2018-04-22 Thread Zelphir Kaltstahl
I am sorry, I think I am still misunderstanding it.

When I try:

(regexp-try-match #rx"^[1-9]+[0-9]*$" (current-input-port))

It also results immediately in:

 #f

> "^" doesn't match the beginning of the input

Is there something else I should use to start matching from the
beginning of whatever I input?

The docs for regexp-try-match say:

> This procedure is especially useful with a pattern that begins with a
start-of-string ^or with a non-#f end-pos, since each limits the amount
of peeking into the port.

To me it sounds like: 'Use this when you want to do "^somethingsomething".'

If I leave away the ^ part:

(regexp-try-match #rx"[1-9]+[0-9]*$" (current-input-port))

It again never stops wanting more input on REPL.


On 22.04.2018 14:34, Matthew Flatt wrote:
> Try `regexp-try-match`.
>
> The `regexp-match` function on an input port consumes non-matching
> input, which means that it consumes all input if a pattern that starts
> "^" doesn't match the beginning of the input.
>
> (This behavior is mentioned in the docs for `regexp-match`, but the
> docs have to say so many things that it's easy to overlook that
> detail.)
>
> At Sun, 22 Apr 2018 05:03:18 -0700 (PDT), Zelphir Kaltstahl wrote:
>> I am trying to match a whole string, to be an integer number.
>>
>> My thinking is, that an integer starts with a non zero digit and then goes 
>> on with an arbitrary number of digits (including zero).
>> I put it in a regexp as follows:
>>
>> (regexp-match #rx"[1-9]+[0-9]*" (current-input-port))
>>
>> But this is not correct, as Racket will try to match this anywhere in the 
>> string. For example it will give me the list containing "1" as a result 
>> when I input "01". I have to specify, that it shall match the whole string. 
>> So I add ^ and $ to it:
>>
>> (regexp-match #rx"^[1-9]+[0-9]*$" (current-input-port))
>>
>> But when I try this on the REPL, it never stops wanting to receive more 
>> input. No matter how many times I press the enter key, it only jumps to a 
>> new line, expecting more input.
>> On 
>> https://docs.racket-lang.org/reference/regexp.html#%28def._%28%28quote._~23~25k
>> ernel%29._regexp-match%29%29 
>> under 4.7.1 circumflex and dollar sign are said to be start and end, so I 
>> am not sure what I am doing wrong.
>> Is it the fact that the input stream does not really end and begin?
>>
>> When I try:
>>
>> (regexp-match #rx"[1-9]+[0-9]*" (read-line (current-input-port) 'any))
>>
>> I get immediately #f, as if I already entered something. (OK I pressed 
>> enter to run that line of code …)
>>
>> How do I solve this problem?
>>
>> -- 
>> 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] Regexp question matching a whole string

2018-04-22 Thread Zelphir Kaltstahl
I am trying to match a whole string, to be an integer number.

My thinking is, that an integer starts with a non zero digit and then goes 
on with an arbitrary number of digits (including zero).
I put it in a regexp as follows:

(regexp-match #rx"[1-9]+[0-9]*" (current-input-port))

But this is not correct, as Racket will try to match this anywhere in the 
string. For example it will give me the list containing "1" as a result 
when I input "01". I have to specify, that it shall match the whole string. 
So I add ^ and $ to it:

(regexp-match #rx"^[1-9]+[0-9]*$" (current-input-port))

But when I try this on the REPL, it never stops wanting to receive more 
input. No matter how many times I press the enter key, it only jumps to a 
new line, expecting more input.
On 
https://docs.racket-lang.org/reference/regexp.html#%28def._%28%28quote._~23~25kernel%29._regexp-match%29%29
 
under 4.7.1 circumflex and dollar sign are said to be start and end, so I 
am not sure what I am doing wrong.
Is it the fact that the input stream does not really end and begin?

When I try:

(regexp-match #rx"[1-9]+[0-9]*" (read-line (current-input-port) 'any))

I get immediately #f, as if I already entered something. (OK I pressed 
enter to run that line of code …)

How do I solve this problem?

-- 
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] Using serial-lambda to send lambdas to places

2018-04-16 Thread Zelphir Kaltstahl
Thanks for the example code.

I will look at it soon, when I can code on that code again and see where
I can get. Seems I misunderstood and thought you were suggesting to use
the non-ergonomic way of identifying procedures for serial-lambda.
That's probably, because I do not understand the source code of the
serial-lambda macro, which I looked at for a moment.

So maybe serial-lambda will save me in the end : ) Will try soon and
thank you! (I think I should also reorganize the code in the repo,
because all the comments make it hard to grasp a lot of the code at one
look. Maybe need to split things up and write comments or explanations
at the top in a lot of detail and references to the code and then just
let the code be there.)


On 15.04.2018 22:47, Philip McGrath wrote:
> If an example would be helpful, here's a toy implementation of
> `parallel-set-map` that uses `serial-lambda` to send the user-supplied
> function across the place-channels:
>
> #lang racket
>
> (require web-server/lang/serial-lambda
>  racket/serialize
>  )
>
> (define (place-printf pch fmt . args)
>   (place-channel-put pch (apply format fmt args)))
>
> (define (spawn-worker id pch print-pch srl-proc)
>   (place/context _
>     (define proc
>   (deserialize srl-proc))
>     (let loop ()
>   (let* ([v (sync pch)]
>  [rslt (proc v)])
>     (place-printf print-pch "place ~a:\t~a -> ~a\n" id v rslt)
>     (place-channel-put pch rslt)
>     (loop)
>
> (define/contract (parallel-set-map proc st send-print-pch)
>   (-> (and/c serializable? (-> any/c any/c))
>   (set/c any/c)
>   place-channel?
>   any/c)
>   (define-values {manager-pch worker-pch}
>     (place-channel))
>   (define workers
>     (for/list ([id (in-range 2)])
>   (spawn-worker id worker-pch send-print-pch (serialize proc
>   (define count
>     (for/sum ([v (in-set st)])
>   (place-channel-put manager-pch v)
>   1))
>   (define results
>     (let loop ([so-far (set)]
>    [i 1])
>   (define st
>     (set-add so-far (sync manager-pch)))
>   (if (= i count)
>   st
>   (loop st (add1 i)
>   (for-each place-kill workers)
>   results)
>
> (define (try-it)
>   (define example-set
>     (set 1 2 3))
>   (define-values {get-print-pch send-print-pch}
>     (place-channel))
>   (thread (λ ()
>     (let loop ()
>   (write-string (sync get-print-pch) (current-output-port))
>   (loop
>   (place-printf send-print-pch
>     "~v\n"
>     (parallel-set-map (serial-lambda (x)
>     (+ x x))
>   example-set
>   send-print-pch))
>   (place-printf send-print-pch
>     "~v\n"
>     (parallel-set-map (serial-lambda (x)
>     (* x x))
>       example-set
>   send-print-pch)))
>
>
> -Philip
>
> On Sun, Apr 15, 2018 at 3:08 PM, Philip McGrath
> <phi...@philipmcgrath.com <mailto:phi...@philipmcgrath.com>> wrote:
>
> On Sun, Apr 15, 2018 at 2:51 PM, Zelphir Kaltstahl
> <zelphirkaltst...@gmail.com <mailto:zelphirkaltst...@gmail.com>>
> wrote:
>
> Having to write all things in terms of where things come from
> like in:
>
> > '([racket/base +] . [1 2])
>
> is not ergonomic at all.
>
>
> Absolutely! To be clear, I was not suggesting that you use that
> format in practice: I was trying to illustrate part of the
> low-level mechanism by which `serial-lambda` (and
> `racket/serialize` in general) work.
>
> Using `serial-lambda` does all of the difficult accounting for you
> to make sure the right function from the right module is there
> when you deserialize it and to arrange for the serializable
> procedure to take its lexical environment along with it. You do
> have to be sure that you're dealing with pure functions and
> serializable data structures, but you can use it as a drop-in
> replacement for `lambda` and get surprisingly far before you have
> to think about any of the details.
>
>

-- 
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] Using serial-lambda to send lambdas to places

2018-04-15 Thread Zelphir Kaltstahl
e` would
> violate the safety guarantees that places provide by requiring
> explicit message-passing rather than shared state.
>
> That means, if you want one place to tell another to call a function,
> you need to send it some kind of immutable message telling it what to
> do. It's rather like calling an API over the network. Let's say you
> want to run tell some place to execute the following thunk:
> (λ ()
>   (+ 1 2))
>
> How might you represent that function as data?
>
> Well, if a function is available as a module-level export, you can
> access it with `dynamic-require`, so a natural way to represent "call
> this function with these arguments" would be with a list of arguments
> for `dynamic-require` to get the function you have in mind, plus a
> list of the arguments to give to the function. The example above might
> be represented like this:
> '([racket/base +] . [1 2])
>
> The receiver place could then interpret such a message like this:
> (λ (message)
>   (apply (apply dynamic-require (car message))
>  (cdr message)))
>
> That's essentially how `serial-lambda` works under the hood. Each
> syntactic use of the `serial-lambda` macro is turned into a
> module-level structure type definition that implements
> `prop:procedure`. When a use is evaluated and a closure is allocated,
> it creates an instance of that structure type, packaging up its free
> lexical variables into the structure's fields (that's the hard part).
> The `prop:serializable` protocol for `racket/serialize` essentially
> records the same information you would need to use `dynamic-require`.
>
> So, to answer some of your specific questions:
>
> On Sun, Apr 15, 2018 at 10:51 AM, Zelphir Kaltstahl
> <zelphirkaltst...@gmail.com <mailto:zelphirkaltst...@gmail.com>> wrote:
>
> - What if in that serial-lambda the user needs to use some custom
> procedure? Does that suddenly also have to be serializable? What about
> its "dependencies"? --> everything in the user program ends up being a
> serial-lambda. That would be really bad.
>
>
> For the procedure value to be serializable, all of the values it
> lexical closes over have to be serializable. If you remember that
> those values have to be packaged up into fields of a struct, this
> makes sense: a list is also only serializable if its contents are
> serializable.
>
> It takes some experience to readily recognize just what it is that an
> anonymous function will close over. One helpful rule is that
> module-level variables are never part of the closure, so they aren't
> required to be serializable: thus, it's ok that things like + aren't
> serializable. On the other hand, in this example:
> (define (make-thunk x)
>   (serial-lambda ()
>     (println x)))
> the function returned by make-thunk will only be serializable when `x`
> is serializable.
>
> You can find some more background about this in the #lang web-server
> documentation. I also wrote some notes on serialization pitfalls for
> the `web-server/formlets` library, which (now) uses serializable
> procedures internally:
> http://docs.racket-lang.org/web-server/formlets.html#%28part._.Formlets_and_.Stateless_.Servlets%29
> <http://docs.racket-lang.org/web-server/formlets.html#%28part._.Formlets_and_.Stateless_.Servlets%29>
>  
>
> - Is there a better way than requiring everything to be serial-lambda?
>
>
> With the caveat that, as I said, not "everything" has to use
> serial-lambda, I don't think there is a better way. Any other solution
> for serializing an arbitrary function would just end up
> re-implementing what `web-server/lang/serial-lambda` does (and has
> been tested and used in production doing). I can think of things that
> `serial-lambda` doesn't do—for example, I've experimented with trying
> to find a mechanism for serialized procedures to take their contracts
> with them—but I would want to use `serial-lambda` to implement such
> additional features, not replace `serial-lambda`. It does its job very
> well.
>  
>
> - Is the idea to have lambdas be serializable by default language wide
> insane? It would be great to be able to simply start a new place and
> give it some arbitrary lambda to execute.
>
>
> #lang web-server/base is just like #lang racket/base, except newly
> created functions are serializable by default (as are continuations).
> However, there is overhead in making a function serializable, and it
> probably wouldn't be a good default for the overwhelming majority of
> functions that nobody ever wants to serialize.
>
> Finally, on a broader point, I don't think you can avoid having to
> think about the fact that your code is going to

[racket-users] Using serial-lambda to send lambdas to places

2018-04-15 Thread Zelphir Kaltstahl
Today I wrote some example code for trying out `serial-lambda` from
`(require web-server/lang/serial-lambda)`. Here is what I currently have:


#lang racket

(require web-server/lang/serial-lambda)
(require racket/serialize)

(define to-send (serial-lambda (x) (* x x)))
(define to-send-2
  (serial-lambda (place-id data)
 (list 'result
   place-id
   (for/list ([i (range 1000)]
  [elem (in-cycle data)])
 (* i elem)
(define to-send-3
  (serial-lambda (place-id data custom-proc)
 (list 'result
   place-id
   (custom-proc
    (for*/list ([i (range 1000)]
   [elem data])
  (* i elem))

(define (custom-proc lst)
  (map (λ (x) (* 2 x))
   lst))

(to-send 4)

(fprintf (current-output-port)
 "Serialized lambda:~a~n"
 (serialize to-send))
(fprintf (current-output-port)
 "Deserialized Serialized lambda: ~a~n"
 (deserialize (serialize to-send)))
(fprintf (current-output-port)
 "Deserialized Serialized lambda of 4: ~a~n"
 ((deserialize (serialize to-send)) 4))

(fprintf (current-output-port)
 "Deserialized Serialized lambda of 4: ~a~n"
 ((deserialize (serialize to-send-2)) 3 '(0 1 2 3)))

(fprintf (current-output-port)
 "lenght Deserialized Serialized lambda of 4: ~a~n"
 (length (caddr ((deserialize (serialize to-send-2)) 3 '(0 1 2
3)

(fprintf (current-output-port)
 "lenght Deserialized Serialized lambda of 4: ~a~n"
 ((deserialize (serialize to-send-3)) 3 '(0 1 2 3) custom-proc))
(fprintf (current-output-port)
 "lenght Deserialized Serialized lambda of 4: ~a~n"
 (length
  (caddr
   ((deserialize (serialize to-send-3)) 3 '(0 1 2 3) custom-proc


Which I can simply run with `racket serial-lambda-example.rkt`. Some
time ago I started a project called "work-distributor"
(https://github.com/ZelphirKaltstahl/work-distributor), which I want to
be usable in a way, that users can simply give some lambda to the
distributor and some data, so that the distributor then creates as many
places as specified and distributes the data and lambda to these places.
Then the places should apply the lambda to their portion of the data and
return the results, which the work distributor would merge and return to
the user / caller.
So far the theory.

As it turns out I cannot send lambdas on place channels
(https://docs.racket-lang.org/reference/places.html?q=place-message-allowed%3F#%28def._%28%28lib._racket%2Fplace..rkt%29._place-message-allowed~3f%29%29),
so the first issue is, that I have to use an import
(require web-server/lang/serial-lambda)to use something from a
completely unrelated package, in order to get a lambda, which can be
serialized and then send that on the place channel. That would not be so
bad, if it was constrained to that one usage, when the user builds their
lambda, which is going to be given to the work distributor, so that the
work distributor can go on and send it to places.
In a user program however, such serial-lambda seems to be "infectious":

- What if in that serial-lambda the user needs to use some custom
procedure? Does that suddenly also have to be serializable? What about
its "dependencies"? --> everything in the user program ends up being a
serial-lambda. That would be really bad.
- OK, lets say the procedure is visible from the places ... I cannot
seriously require the user of the work distributor to go into the code
of the work distributor and add custom procedures there. That would be
like requiring them to write custom parallelization code.

Maybe I am missing something simple in this whole line of thought.

- Is there a better way than requiring everything to be serial-lambda?
- Is there a better way than requiring the user to edit the work
distributor code to make custom procedures available to the places?
- Is the idea to have lambdas be serializable by default language wide
insane? It would be great to be able to simply start a new place and
give it some arbitrary lambda to execute.

-- 
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] Re: The Racket School 2018: Create your own language

2018-03-21 Thread Zelphir Kaltstahl
I also think it would be great to have the material online at some later
point in time (I guess not simultaneously). Learning how to create a
language using Racket is one of the things I kept postponing so far,
because I think of it to involve a lot of difficult macro magic and
other difficult things, but maybe I am wrong and could already be
writing my own for special use-cases. So I find it very interesting, but
there is no chance I can go there to participate.

-- 
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] Re: Non-blocking place get

2018-02-22 Thread Zelphir Kaltstahl
(Lets try this answering to a topic via e-mail thing. Here goes …)

With a lot of help from people in the Racket user group the following
was recently created: https://github.com/ZelphirKaltstahl/work-distributor
Maybe its code can also be helpful to you.

-- 
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] Re: Installing Racket Package `gregor` inside a Docker container

2018-01-01 Thread Zelphir Kaltstahl
I finally managed to do what I want using the installer approach from Jack 
Firth's Dockerfile:

~~

# DEBIAN IMAGE #

FROM debian:jessie


# META #

MAINTAINER "Zelphir Kaltstahl <zelphirkaltst...@gmail.com>"

#
# ENVIRONMENT VARIABLES #
#
ENV SHELL=/bin/bash
ARG ROOT_USER=root
ARG DEBIAN_FRONTEND=noninteractive
ARG NON_PRIVILEGED_USER=app
ARG NON_PRIVILEGED_USER_GROUP=app
ARG NON_PRIVILEGED_USER_PASSWORD="yourpw"
ENV HOME="/home/${NON_PRIVILEGED_USER}"

###
# SYSTEM PACKAGES #
###
USER $ROOT_USER
RUN apt-get update
RUN apt-get --yes upgrade
# --no-install-recommends\
RUN apt-get --yes dist-upgrade \
 && apt-get install -y \
wget \
sqlite3 \
openssl \
ca-certificates \
sudo \
locales \
git \
bzip2 \
unzip
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*
##
# SET LOCALE #
##
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && 
\
echo 'LANG="en_US.UTF-8"' > /etc/default/locale && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8

#
# ADDING A USER #
#
# For more info please check useradd --help or man useradd.
RUN groupadd -r $NON_PRIVILEGED_USER_GROUP -g 1000 \
 && useradd \
--uid 1000 \
--system \
--gid $NON_PRIVILEGED_USER_GROUP \
--create-home \
--home-dir /home/$NON_PRIVILEGED_USER/ \
--shell /bin/bash \
--comment "non-privileged user" \
$NON_PRIVILEGED_USER \
 && chmod 755 /home/$NON_PRIVILEGED_USER/ \
 && echo "$NON_PRIVILEGED_USER:$NON_PRIVILEGED_USER_PASSWORD" | chpasswd

###
# INITIAL WORKDIR #
###
WORKDIR $HOME

##
# RACKET #
##
USER $NON_PRIVILEGED_USER

ARG 
RACKET_INSTALLER_CHECKSUM="85cbff83f202293b6cd4c3c58e97919fd75a963177ae815a0e9186886ca4fc54"
ARG RACKET_INSTALLER_FILENAME="racket-install.sh"
ARG RACKET_VERSION="6.11"
ARG 
RACKET_INSTALLER_URL="https://mirror.racket-lang.org/installers/${RACKET_VERSION}/racket-minimal-${RACKET_VERSION}-x86_64-linux.sh;
# download
RUN wget --output-document=$RACKET_INSTALLER_FILENAME -q 
$RACKET_INSTALLER_URL \
 && printf "${RACKET_INSTALLER_CHECKSUM} ${RACKET_INSTALLER_FILENAME}" | 
sha256sum -c - \
 && printf "no\n3\n" | /bin/bash racket-install.sh
# cleanup
RUN rm racket-install.sh
# setup
WORKDIR racket/bin
RUN chmod +x racket
RUN chmod +x raco
RUN printf "b"
ENV PATH=$HOME/racket/bin:$PATH
RUN printf "%s\n" $PATH
# RUN which racket
RUN raco setup
RUN raco pkg config --set catalogs\
"https://download.racket-lang.org/releases/$RACKET_VERSION/catalog/"\
"https://pkg-build.racket-lang.org/server/built/catalog/"\
"https://pkgs.racket-lang.org"\
"https://planet-compats.racket-lang.org;

###
# RACKET PACKAGES #
###
USER $NON_PRIVILEGED_USER
RUN yes | raco pkg install --auto --jobs 4 markdown
RUN yes | raco pkg install --auto --jobs 4 yaml
RUN yes | raco pkg install --auto --jobs 4 pollen
RUN yes | raco pkg install --auto --jobs 4 gregor
RUN yes | raco pkg install --auto --jobs 4 sha

#
# INSTALL MINICONDA #
#
USER $NON_PRIVILEGED_USER
WORKDIR $HOME

ARG MINICONDA_VERSION="4.3.30"
ENV 
MINICONDA_SHA256SUM="66c822dfe76636b4cc2ae5604816e0e723aa01620f50087f06410ecf5bfdf38c"
ENV CONDA_DIR $HOME/anaconda
ENV PATH $CONDA_DIR/bin:$PATH

RUN mkdir --parents $CONDA_DIR \
 && wget --quiet 
https://repo.continuum.io/miniconda/Miniconda3-$MINICONDA_VERSION-Linux-x86_64.sh
 
\
 && echo "${MINICONDA_SHA256SUM} 
Miniconda3-$MINICONDA_VERSION-Linux-x86_64.sh" | sha256sum -c - \
 && /bin/bash Miniconda3-$MINICONDA_VERSION-Linux-x86_64.sh -f -b -p 
$CONDA_DIR \
 && rm Miniconda3-$MINICONDA_VERSION-Linux-x86_64.sh \
 && $CONDA_DIR/bin/conda config --system --add channels conda-forge \
 && $CONDA_DIR/bin/conda config --system --set auto_update_conda false \
 && conda clean -tips --yes

###
# PYTHON PACKAGES #
###
RUN conda install --yes --quiet pygments

#
# COPY BLOG #
#
COPY blog $HOME/blog


# FINALIZE #

USER $NON_PRIVILEGED_USER
WORKDIR $HOME/blog
# ENTRYPOINT ["tini", "--"]

# TODO: Why are variables not working in the CMD directive of Dockerfiles?
CMD ["/home/app/racket/bin/racket", "server.rkt"]
~~

Note that I had to switch to `printf` instead of `echo` for the Racket 

[racket-users] Re: [ANN] Porting PAIP's Prolog interpreter from Common Lisp to Racket - Part 2

2017-12-26 Thread Zelphir Kaltstahl
This looks very interesting! I am not that far yet, so I don't really have 
any enhancement suggestions, but it is great to see some work being done in 
this area. 

-- 
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] match in Lazy Racket?

2017-12-08 Thread Zelphir Kaltstahl
Thank you for this quick and easy solution, this help!

I am still curious however, why it is in such a way, that so many other 
forms are available, but `match` must be required. I could imagine that 
`match` is a complex thing under the covers, but I am not sure whether that 
is the reason or something else.

Or maybe there is even a general reason for multiple forms not being 
available in Lazy Racket?
If there is no general reason, maybe we can create a list of not available 
ones and put it in the Lazy Racket docs, including ways, if there are any, 
to get the forms available when using Lazy Racket.

On Friday, December 8, 2017 at 10:29:02 PM UTC+1, Ben Greenman wrote:
>
> You can `(require racket/match)`. Make sure to force the match expression! 
>
> #lang lazy 
> (require racket/match) 
>
> (match (! (string->symbol "a")) 
>   ['a 'a] 
>   ['b 'b]) 
>

-- 
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] match in Lazy Racket?

2017-12-08 Thread Zelphir Kaltstahl
I played a bit with lazy Racket and when I used `match`:

~~~
#lang lazy

(match 'a
  ['a 'a]
  ['b 'b])
~~~

In Emacs in racket-mode the `match` was underlined and I was told that:

~~~
match: unbound identifier in module
~~~

Is there truly no match possible in lazy Racket? What is the reasoning 
behind this?

-- 
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] Re: Unit test inner procedures

2017-11-27 Thread Zelphir Kaltstahl
Huh, that looks reasonable.
So far I've not used modules much, except the implicit one by:
~~~
#lang racket
~~~
So the example is helpful.
The tests are not in another file, but at least they are not inside a 
wrapping procedure and are in a way separate.
Maybe I should have a look at the different ways of defining modules again 
and use them more.

On Monday, November 27, 2017 at 10:15:38 PM UTC+1, Jack Firth wrote:
>
> I don't think you can directly test an inner procedure while keeping your 
> test code separately loadable (e.g. different file or module). It doesn't 
> seem like a good idea to me, personally. Inner procedures communicate to me 
> that I can change, reorganize, delete, and otherwise do whatever I want to 
> them without breaking any code outside the definition of the outer 
> procedure. Breaking tests in a different file with a refactoring of an 
> inner procedure would be *very *surprising to me.
>
> Instead, I recommend not using inner procedures so extensively. Instead 
> define functions within modules (or possibly submodules) and use `provide` 
> with `contract-out` to declare which functions make the public API of your 
> module. You can then add a test submodule which has access to the inner 
> workings of the outer module and test "private" helper functions that way. 
> Here's an example:
>
> #lang racket;; note that using #lang implicitly creates a module around 
> the whole file
>
> (provide
>   (contract-out
> [my-public-function (-> input? output?)]))
>
> (define (my-public-function input)
>   (helper2 (helper1 input)))
>
> (define (helper1 input) ...)
> (define (helper2 input) ...)
>
> (module+ test ;; inside this submodule we can see helper1 and helper2, 
> even though they're not provided
>   (require rackunit)
>   (check-equal? (helper1 test-input) test-output)
>   ... more tests here ...)
>

-- 
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] Unit test inner procedures

2017-11-27 Thread Zelphir Kaltstahl
Sometimes I find myself thinking: "I should really write some tests for all 
of this!"
But then I ask myself: "Uhm, how can I test some of the inner procedures of 
this procedure?"

I sometimes use inner procedures when no other part of the code needs 
access to some procedure and it fits purpose-wise into that wrapping 
procedure.
It is also helpful to wrap things, which I want to be exchangeable. For 
example for some xexpr rendering on a website, I could make a renderer for 
the whole website, which then internally is broken down into parts, which 
are all implemented by their own procedures, which are inner procedures to 
the all-wrapping renderer. This way I can return some procedure which uses 
these inner procedures (its in the closure's environment). This seems very 
useful to me and I would like to keep some code that way. It also keeps 
namespaces cleaner and makes naming easier, because a procedure inside a 
wrapping procedure can have simpler names than outside of it in some cases.

However I have this problem of "How to unit test these inner procedures?" 
Ideally I would not need to put tests into the wrapping procedure, but 
could keep the tests separate in another file.

Here is some code example:

~~~
(define (modulator clazz)
  (define (modulo a-number)
(remainder a-number clazz))
  modulo)
(let ([my-modulator (modulator 7)])
  (displayln "My modulator will do the job!")
  (my-modulator 50))
~~~

(OK this is a very artificial example.)
How would I unit test the `modulo` procedure, without taking it outside of 
its wrapping procedure? Is there an easy way this can be done? (or maybe 
inner procedure unit testing is a big no-no? If so, why?)

-- 
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] Re: Alternatives to DrRacket

2017-11-27 Thread Zelphir Kaltstahl
I mostly like the text navigation features I have in Emacs. I also like 
that I can run a shell inside Emacs and manage multiple buffers easily. 
Installing different color themes is easy too, while in DrRacket I would 
probably have to configure the colors myself (I might be wrong though, not 
sure if there isn't an easy way to get many themes into DrRacket).

I've never used DrRacket for a long time. Even the fancy arrows where 
something comes from when you hover it with the mouse cursor did not do 
much for me, because I either already knew where it came from, because I 
wrote the code myself, or because the arrow would come from something out 
of visible area. This also happens when you have an error and it tries to 
help you with the arrows. If it was somehow more usable (I have no idea 
how), maybe it would do something for me too.
What I used DrRacket for once were the examples for multi-threading and 
multi-processing in the Racket guide. It has nice visualization for this 
stuff, which I cannot get easily from Emacs.

When I need more of a backtrace, I simply run my programs with: `racket -l 
errortrace -t myfile.rkt` (that is a lowercase L, not an uppercase i)
Memory limits can be easily added to a program as well with the following 
code:

~~~
(define (Mb-to-B n) (* n 1024 1024))
(define MAX-BYTES (Mb-to-B 128))
(custodian-limit-memory (current-custodian) MAX-BYTES)
~~~

So I am usually not missing anything DrRacket would give me. Maybe if I was 
using more languages or more of the debugging tooling it offers I would use 
DrRacket more often.
One thing I liked was the integrated package manager. But that too can be 
handled easily with the `raco`.

-- 
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] Re: Need help with parallelizing a procedure

2017-08-22 Thread Zelphir Kaltstahl
Will "The Seasoned Schemer" be understandable for people who did not read the 
"The Little Schemer"? And is what is in there directly applicable in Racket (I 
guess it is, because of Racket's background, but I better ask beforehand!)

So far I've read some part of SICP (Chapter 1 & 2), part of Realm of Racket and 
did some small Racket projects.

-- 
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] Re: Need help with parallelizing a procedure

2017-08-19 Thread Zelphir Kaltstahl
I looked at the code for a while again and think I now begin to understand it a 
bit more:

I did not know `(let/ec` so I had to read about it. It says, that it is 
equivalent to `(call/ec proc` or something, which is equivalent to 
`(call-with-escape-continuation ...`. Uff … I don't know much about 
continuations, except from a vague idea of when they are called. The idea gets 
mingled with structures in other programming languages which are "catching 
exceptions" and such stuff. I don't know this stuff, so I guess 
`(call-with-escape-continuation` works like catching an exception, which is not 
really an exception, but just a signal, that code is returning. Then instead of 
simply returning, the escape continuation is called. This is done implicitly 
without specifying a named exception for returning and without defining some 
conditional structure on the side where it would return to.

This could all be wrong and all I found was the following very unhelpful 
https://lists.racket-lang.org/users/archive/2010-October/042356.html where it 
links me to some paper (https://www.cs.indiana.edu/~dfried/appcont.pdf), which 
I have no motivation to read in its entirety, even if it's probably really 
clever stuff. Maybe that is the actual reason: Fearing that I wont understand 
any of it in depth. It also includes some exercises, which seem to be really 
difficult.

However, with this kind of idea about escape continuations in mind, I think I 
get the idea behind using `(let/ec` in the code. When a place wants to exit, it 
is stopped from doing so, giving it more work, as if to say: "Hey wait! You can 
escape, but only if you do THIS! (escape continuation)" Then the place, 
desperately wanting to escape thinks: "Damn, OK, I'll do just that little bit 
of code more.", not realizing, that it is stuck in a loop. How mean.

I wonder however, if there is no simpler way of doing this.

I mean, if `(place-channel-get ...)` blocks, could I simply put stuff into an 
endless loop without escape continuation and only break the loop, if a certain 
symbol is received on the channel?

Since `(place-channel-get ...)` is blocking, it should not generate any CPU 
load, when there is no message on the channel (right?).

Why do I need to introduce something as complex as `(let/ec ...)`?

I appreciate the code shared here. I just hesitate to use it, when I don't even 
understand it myself or when I am super unsure about understanding it (escape 
continuations). I am also thinking about how I can replace all the exclamation 
mark procedures, before adding it to my other code, which does not deal with 
assignments so far.

Is there some easy to understand introduction to continuations in Racket? (not 
a super clever and scientific Friedman paper, which I'd probably need 1 year to 
actually understand :D)

-- 
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] Re: Need help with parallelizing a procedure

2017-08-16 Thread Zelphir Kaltstahl
Just a few quick questions regarding the places code:

1. Is `?` like `if`? For me it says that it is an undefined identifier.
2. If I understand correctly, the place is looping and in each iteration is 
looks if there is a message on the channel, which matches something. Is this 
creating a lot of extra work for looking on the channel all the time?
3. What are `p`, `_i`, `_o` and `_e` doing?
4. Could I replace `set!-values` with a `let`?

-- 
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] Re: Need help with parallelizing a procedure

2017-08-14 Thread Zelphir Kaltstahl
Thanks for the example code, I'll try it soon!

The whole code is on my repository at:

  https://github.com/ZelphirKaltstahl/racket-ml/blob/master/decision-tree.rkt

I tried with feature-visualizer, but did not save screenshots of the result. 
Would it help showing them? I was not able to figure out the problem, even when 
clicking the red dots to see what is blocking. It made no sense to me, that 
those operations were blocking. However, I tried a lot of things and don't 
remember what procedures were blocking in which case. I remember, that I once 
tried to use flonum operations and that even they were shown to be blocking, 
while they solved the problem in the guide for parallelization in Racket.

When I ran my whole decision tree program with some example data and the 
statistical profiler package, I found that the algorithm spent most time as 
follows (for the code in the repository, possibly dev branch):

- data-majority-prediction = 15084(32.4%)
- calc-proportion  = 15656(33.6%)
- get-best-split   = 4304(9.2%)
- gini-index   = ??? (but is part of get-best-split)

-- 
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] Re: Need help with parallelizing a procedure

2017-08-13 Thread Zelphir Kaltstahl
I tested using futures. While it is significantly faster than creating places, 
it is still also significantly slower than the single threaded solution without 
places and without futures:

~~~
(define (gini-index-futures subsets label-column-index)
  (let ([futures (flatten (for/list ([subset (in-list subsets)])
(for/list ([label (in-list (list 0 1))])
  (future (lambda ()
(calc-proportion subset
 label
 
label-column-index))])
(for/sum ([a-future (in-list futures)])
  (touch a-future
~~~

There always seems to be something blocking, so that only one core is used by 
the futures. Creating places is too expensive, so maybe I could create places 
at the very beginning before my program runs and always re-use those.

-- 
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] Re: Need help with parallelizing a procedure

2017-08-12 Thread Zelphir Kaltstahl
On Saturday, August 12, 2017 at 12:21:19 PM UTC+2, Zelphir Kaltstahl wrote:
> I want to parallelize a procedure which looks like this:
> 
> ~~~
> (define (gini-index subsets label-column-index)
>   (for/sum ([subset (in-list subsets)])
> (for/sum ([label (in-list (list 0 1))])
>   (calc-proportion subset
>label
>label-column-index
> ~~~
> 
> I tried some variations of using places without success and then I found: 
> https://rosettacode.org/wiki/Parallel_calculations#Racket
> 
> Where the code is:
> 
> 
> ~~~
> #lang racket
> (require math)
> (provide main)
>  
> (define (smallest-factor n)
>   (list (first (first (factorize n))) n))
>  
> (define numbers 
>   '(112272537195293 112582718962171 112272537095293
> 115280098190773 115797840077099 1099726829285419))
>  
> (define (main)
>   ; create as many instances of Racket as
>   ; there are numbers:
>   (define ps 
> (for/list ([_ numbers])
>   (place ch
>  (place-channel-put 
>   ch
>   (smallest-factor
>(place-channel-get ch))
>   ; send the numbers to the instances:
>   (map place-channel-put ps numbers)
>   ; get the results and find the maximum:
>   (argmax first (map place-channel-get ps)))
> ~~~
> 
> So inside the list places are created and it seems that the whole definition 
> of what they are supposed to do is wrapped in that (place ...) expression. I 
> tried to do the same for my example:
> 
> ~~~
> (define (gini-index subsets label-column-index)
>   (for*/list ([subset (in-list subsets)]
>   [label (in-list (list 0 1))])
> (place pch
>(place-channel-put pch (list subset label label-column-index))
>(let ([data (place-channel-get pch)])
>  (calc-proportion (first data)
>   (second data)
>   (third data))
> ~~~
> 
> The `subset` inside `(place-channel-put pch (list subset label 
> label-column-index))` gets underlined and the error is:
> 
> subset: identifier used out of context
> 
> (I) In the example from Rosetta code it is all easy, as here is only passed 
> one number and is does not need a name or anything, but in my example I am 
> not sure how to do it.
> 
> (II) A second thing I tried to do was using a place more than once (put, get 
> then put get to the channel again), but it did not work and my program simply 
> did nothing anymore, no cpu load or anything, but also did not finish, 
> probably waiting for an answer from the place and never getting any. Is it in 
> general not possible to use a place more than once?

Meanwhile I could find a way to use places which is the following:

~~~
(define (gini-index subsets label-column-index)
  ;; (displayln "1 calculating gini index")
  #|
  Takes:
  - a list of place descriptors
  - subsets (should always be two in this implementation)
  - labels (should alway be a (list 0 1)
  Returns:
  - a list of place descriptors
  |#
  (define (iter-subsets subsets labels place-descriptors)  ; call with empty
(cond [(empty? subsets) place-descriptors]
  [else (iter-subsets (rest subsets)
  labels
  (cons (iter-labels (first subsets) labels empty)
place-descriptors))]))

  (define (iter-labels subset labels place-descriptors)
(cond [(empty? labels) place-descriptors]
  [else (let ([a-place (dynamic-place "decision-tree-places.rkt"
  'place-calc-proportion-main)])
  (place-channel-put a-place
 (list subset (first labels) 
label-column-index))
  (iter-labels subset
   (rest labels)
   (cons a-place place-descriptors)))]))

  (let ([places (flatten (iter-subsets subsets (list 0 1) empty))])
(let ([result (for/sum ([a-place (in-list places)])
(place-channel-get a-place))])
  (display "result: ") (displayln result)
  result)))
~~~

I could not find a more elegant solution for creating the places and keeping a 
handle on them for calling place-channel-get on them.

However, my tests confirm exactly what you said: It's wy slower than even 
the single core implementation. The overhead seems to be huge for starting 
another Racket instance and all that goes with that.

I wondered about futures too, because I read (most of ;) the parallelism guide. 
I only thought that it would not work out, because of actually using 
potentially large lists of vectors and not only floats. I once (some months 
ago) ran the example

[racket-users] Need help with parallelizing a procedure

2017-08-12 Thread Zelphir Kaltstahl
I want to parallelize a procedure which looks like this:

~~~
(define (gini-index subsets label-column-index)
  (for/sum ([subset (in-list subsets)])
(for/sum ([label (in-list (list 0 1))])
  (calc-proportion subset
   label
   label-column-index
~~~

I tried some variations of using places without success and then I found: 
https://rosettacode.org/wiki/Parallel_calculations#Racket

Where the code is:


~~~
#lang racket
(require math)
(provide main)
 
(define (smallest-factor n)
  (list (first (first (factorize n))) n))
 
(define numbers 
  '(112272537195293 112582718962171 112272537095293
115280098190773 115797840077099 1099726829285419))
 
(define (main)
  ; create as many instances of Racket as
  ; there are numbers:
  (define ps 
(for/list ([_ numbers])
  (place ch
 (place-channel-put 
  ch
  (smallest-factor
   (place-channel-get ch))
  ; send the numbers to the instances:
  (map place-channel-put ps numbers)
  ; get the results and find the maximum:
  (argmax first (map place-channel-get ps)))
~~~

So inside the list places are created and it seems that the whole definition of 
what they are supposed to do is wrapped in that (place ...) expression. I tried 
to do the same for my example:

~~~
(define (gini-index subsets label-column-index)
  (for*/list ([subset (in-list subsets)]
  [label (in-list (list 0 1))])
(place pch
   (place-channel-put pch (list subset label label-column-index))
   (let ([data (place-channel-get pch)])
 (calc-proportion (first data)
  (second data)
  (third data))
~~~

The `subset` inside `(place-channel-put pch (list subset label 
label-column-index))` gets underlined and the error is:

subset: identifier used out of context

(I) In the example from Rosetta code it is all easy, as here is only passed one 
number and is does not need a name or anything, but in my example I am not sure 
how to do it.

(II) A second thing I tried to do was using a place more than once (put, get 
then put get to the channel again), but it did not work and my program simply 
did nothing anymore, no cpu load or anything, but also did not finish, probably 
waiting for an answer from the place and never getting any. Is it in general 
not possible to use a place more than once?

-- 
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] Get number of CPUs / Cores

2017-08-08 Thread Zelphir Kaltstahl
Yes that seems to be it, thanks!

-- 
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] Get number of CPUs / Cores

2017-08-08 Thread Zelphir Kaltstahl
I want to parallelize some program using places, so actually using multiple 
cores.

To parallelize as much as possible on any given machine, I'd like to know how 
many cores + effect of hyperthreading there are.

For example I have a CPU with 2 cores, but it supports hyperthreading, so that 
I can run 4 processes concurrently. The desired result would then be 4 instead 
of 2.

At the moment I have the following code, but don't know if this code is at all 
reliable or a good practice:

~~~
(require cpuinfo)
(define (get-number-parallel-units)
  (define (find-siblings remaining-core-info)
(cond [(empty? remaining-core-info) empty]
  [(equal? (car (first remaining-core-info)) 'siblings)
   (string->number (cdr (first remaining-core-info)))]
  [else
   (displayln "not:")
   (displayln (car (first remaining-core-info)))
   (find-siblings (rest remaining-core-info))]))
  (find-siblings (car (get-cpuinfo
~~~

Then with the number of possible maximum number of concurrent processes, I want 
to dynamically create places:

~~~
(let
  ;; dynamically create places
  ([places (for/list ([i (in-range PLACES-COUNT)])
 (dynamic-place "place-worker.rkt" 'place-main))]
   [chunk-size (/ MAX PLACES-COUNT)])
;; give places work to do ...
)
~~~

So what is the best and most reliable way to figure out how many processes can 
run concurrently? (I assume that is the same number as "How many places are 
worth 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.


[racket-users] Re: Decision Tree in Racket - Performance

2017-08-07 Thread Zelphir Kaltstahl
I've now implemented post pruning with 2 test cases as well.

-- 
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] Re: Decision Tree in Racket - Performance

2017-08-01 Thread Zelphir Kaltstahl
I think I've now implemented most of the optimizations mentioned in this topic.

I also adapted my code to use some of the neat things I found in Daniel's code.

The implementation now supports most of the optimization parameters for 
decision trees, which I found on: 
http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html

The updated code is on: https://github.com/ZelphirKaltstahl/racket-ml

One test I find hard to write and that is the one for evaluate-algorithm, 
because of all the things one needs to foresee to write it.

If there are no more obvious significant inefficiencies, I'll mark this topic 
as finished.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-28 Thread Zelphir Kaltstahl
In general what is the opinion on replacing `first` and `rest` with `car` and 
`cdr`, when considering readability?

I find `first` and `rest` very readable and remember that I got quite confused 
when I started learning Racket with all the cadrdrdrd ;) I still think `first` 
and `rest` reads better, but if the performance is that much worse and even 
needs an O(n) check for `list?` ... maybe it's not the right choice.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-28 Thread Zelphir Kaltstahl
On Friday, July 28, 2017 at 2:02:56 AM UTC+2, gustavo wrote:
> I agree with the in-list explanation, but I want to remark a few details.
> 
> >> I don't really understand the (in-list ...) thing. This seems to be 
> >> internal magic to me.
> 
> `in-list` is not a function, it's a macro that looks like a function.
> `for` is another macro (that doesn't look like a function). But in
> Racket the macros are not just straightforward text substitution, they
> can do a lot of things. Most are simple, but some macros are very
> complex. For example `for` can examine some additional information
> stored in `in-list` and write very efficient code. I.e. magic, a lot
> of magic, but you can write your own magical `in-something`. The
> details are in https://docs.racket-lang.org/reference/for.html but
> it's not easy so I recommend reading it later after playing more with
> the simple macros.
> 
> I looked at your solution with vectors. I think that vectors are not
> slower than lists, moreover, they should be slightly faster, but
> sometimes I guess wrong. The problem with your implementation is that
> it creates a lot of intermediate lists. For example in
>(apply + (map (lambda (class-label) ...) class-labels)
> The intermediate list must be allocated and free after use, the values
> are scattered in memory so it may be slower to use them.
> 
> Also, the compiler can write more efficient code for the + in (+ x y)
> than for the + in (apply + ...).
> 
> The solution of Daniel use (for/sum ...) instead of (apply + (map ...)).
> 
> There are a few places that can be rewritten. My recommendation for
> fast code is to try to avoid allocations when possible.
> 
> Gustavo

Thanks, will try to get it done soon! I also don't like the readability aspect 
of some part of code I have, like the nested map summing and initially already 
thought that there must be something better available. It's Racket after all. 
So thanks for pointing it out.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-28 Thread Zelphir Kaltstahl
On Thursday, July 27, 2017 at 10:17:00 PM UTC+2, Daniel Prager wrote:
> > Wow, are those timings for the "big" data set?!
> 
> 
> I use 1/5 of the data as a training set, in line with my understanding of the 
> original article, which splits it in 5.
> 
> I use the remaining 4/5 as a single validation set rather than four separate 
> sets (because I got lazy). That won't impact the speed since validating the 
> model is fast.
> 
> > When I tried I could not run @Daniel's solution. There was some kind of 
> > error. I am running Racket 6.8. Should I update to 6.9, could that be the 
> > issue?
> 
> I'm running on 6.8 as well, so it's not that.
> 
> Are you running on Windows or Linux (I'm on Mac)? 
> 
> 
> You may need to modify the string-split to correctly parse line-endings per 
> Gustavo:
> 
> 
> 
> (string-split s #rx"\r?\n")
> 
> 
> 
> Is that it?
> 
> Dan
> 
> 
> 
> 
> On Fri, Jul 28, 2017 at 6:01 AM, Zelphir Kaltstahl <zelphirk...@gmail.com> 
> wrote:
> 
> 
> On Wednesday, July 26, 2017 at 3:17:46 PM UTC+2, gustavo wrote:
> 
> > I read the solution of Daniel Prager and I have a few minor changes.
> 
> >
> 
> > * First I added a test that repeats `build-tree` 20 times, so the run
> 
> > time is approximately 1-2 seconds. This is not necessary, but times
> 
> > smaller than 1 second are sometimes not reliable. I'm using:
> 
> > ;---
> 
> > (random-seed 12345)
> 
> > (define data2 (shuffle banknote-data))
> 
> > (time
> 
> >  (void
> 
> >   (build-tree (take data2 274) 5 10)))
> 
> > (time
> 
> >  (for ([i (in-range 20)])
> 
> >    (build-tree (take data2 274) 5 10)))
> 
> > ;---
> 
> >
> 
> >
> 
> >
> 
> > * Second I modified the split function so it is usable in Windows and
> 
> > Linux. I'm using:
> 
> >     (string-split s #rx"\r?\n")
> 
> > I'm almost sure this is not the best method to write portable code.
> 
> > Any recommendation?
> 
> >
> 
> >
> 
> >
> 
> > * The most important change is to add `in-list` everywhere, i.e. replace
> 
> >     (for/sum ([split splits])  ...)
> 
> > with
> 
> >     (for/sum ([split (in-list splits)])  ...)
> 
> >
> 
> > I'm not sure that all of them are necessary. The `for` clauses without
> 
> > `in-list` are nice because they are very generic and can iterate over
> 
> > a lot of different data types. The problem is that they create a
> 
> > auxiliary sequence and use the methods of the sequence to iterate, so
> 
> > they are slower than expected. If you use `in-list`, the `for` is
> 
> > expanded to code that is specific to lists and is almost as efficient
> 
> > as the hand coded version like (let loop ([l my-list]) ...) and
> 
> > sometimes better.
> 
> >
> 
> > Most of the times you can use the generic version and use the code
> 
> > with any data type for free, but in the spots where you need fast code
> 
> > remember to use in-range, in-list, in-vector, ... (For the version
> 
> > that uses vectors for internal representation, you should probably use
> 
> > in-vector. I didn't look at the code.)
> 
> >
> 
> > Before this change a typical run time of the test is
> 
> >    cpu time: 157 real time: 165 gc time: 0
> 
> >    cpu time: 3390 real time: 3393 gc time: 63      (20 times)
> 
> >
> 
> > After this change a typical run time of the test is
> 
> >    cpu time: 62 real time: 61 gc time: 0
> 
> >    cpu time: 1266 real time: 1277 gc time: 62     (20 times)
> 
> >
> 
> > Gustavo
> 
> >
> 
> > PS: I made a PR with these changes in github.
> 
> 
> 
> Wow, are those timings for the "big" data set?!
> 
> 
> 
> This is about 20x faster than the vector solution. I wonder where I am 
> loosing so much time. Still not finished implementing everything, but I can 
> build a tree now with the vector solution. One guess I have is, that I am 
> currently (partly for debugging purposes) storing subsets of data in each 
> node of the tree, instead of only the split value. Another is, that I am 
> using structs (instead of minimalistic lists? tagged data?) to represent 
> nodes and they are constructed etc.
> 
> 
> 
> But other than that I have no clue what is using up so much time. Maybe I can 
> time every procedure in DrRacket somehow and see where the most time is spend.
> 
> 
> 
> I am also curious about the Typed Racket ve

[racket-users] Re: Decision Tree in Racket - Performance

2017-07-27 Thread Zelphir Kaltstahl
I had another idea for the implementation, which I tried to implement. I tried 
to store in each node a procedure, which can be used when predicting data point 
labels, so that I can simply get that from the struct and call it with the data 
point and get back, whether I should go left or right at each node.

While this probably works, I have another problem:

The test cases for fitting the decision tree fail now, because the procedures 
are different, although each of them is the same logic, only that they have 
different environments and different line numbers, in which they are created.

Is there a way to compare procedures? I could not find any `procedure-equal?` 
or something like that.

Just to clear it up a little: They are simple lambda expressions like the 
following:

```
(lambda (feature-value)
 (if (< feature-value (Split-value best-split)) 'left 
'right))
```

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-27 Thread Zelphir Kaltstahl
On Wednesday, July 26, 2017 at 3:17:46 PM UTC+2, gustavo wrote:
> I read the solution of Daniel Prager and I have a few minor changes.
> 
> * First I added a test that repeats `build-tree` 20 times, so the run
> time is approximately 1-2 seconds. This is not necessary, but times
> smaller than 1 second are sometimes not reliable. I'm using:
> ;---
> (random-seed 12345)
> (define data2 (shuffle banknote-data))
> (time
>  (void
>   (build-tree (take data2 274) 5 10)))
> (time
>  (for ([i (in-range 20)])
>(build-tree (take data2 274) 5 10)))
> ;---
> 
> 
> 
> * Second I modified the split function so it is usable in Windows and
> Linux. I'm using:
> (string-split s #rx"\r?\n")
> I'm almost sure this is not the best method to write portable code.
> Any recommendation?
> 
> 
> 
> * The most important change is to add `in-list` everywhere, i.e. replace
> (for/sum ([split splits])  ...)
> with
> (for/sum ([split (in-list splits)])  ...)
> 
> I'm not sure that all of them are necessary. The `for` clauses without
> `in-list` are nice because they are very generic and can iterate over
> a lot of different data types. The problem is that they create a
> auxiliary sequence and use the methods of the sequence to iterate, so
> they are slower than expected. If you use `in-list`, the `for` is
> expanded to code that is specific to lists and is almost as efficient
> as the hand coded version like (let loop ([l my-list]) ...) and
> sometimes better.
> 
> Most of the times you can use the generic version and use the code
> with any data type for free, but in the spots where you need fast code
> remember to use in-range, in-list, in-vector, ... (For the version
> that uses vectors for internal representation, you should probably use
> in-vector. I didn't look at the code.)
> 
> Before this change a typical run time of the test is
>cpu time: 157 real time: 165 gc time: 0
>cpu time: 3390 real time: 3393 gc time: 63  (20 times)
> 
> After this change a typical run time of the test is
>cpu time: 62 real time: 61 gc time: 0
>cpu time: 1266 real time: 1277 gc time: 62 (20 times)
> 
> Gustavo
> 
> PS: I made a PR with these changes in github.

Wow, are those timings for the "big" data set?!

This is about 20x faster than the vector solution. I wonder where I am loosing 
so much time. Still not finished implementing everything, but I can build a 
tree now with the vector solution. One guess I have is, that I am currently 
(partly for debugging purposes) storing subsets of data in each node of the 
tree, instead of only the split value. Another is, that I am using structs 
(instead of minimalistic lists? tagged data?) to represent nodes and they are 
constructed etc.

But other than that I have no clue what is using up so much time. Maybe I can 
time every procedure in DrRacket somehow and see where the most time is spend.

I am also curious about the Typed Racket version and consider doing this once I 
am done with the vector solution as well.

I don't really understand the (in-list ...) thing. This seems to be internal 
magic to me. Maybe it informs about the type of what is iterated over and that 
makes it faster?

When I tried I could not run @Daniel's solution. There was some kind of error. 
I am running Racket 6.8. Should I update to 6.9, could that be the issue?

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-25 Thread Zelphir Kaltstahl
I've come to the conclusion, that not assuming binary classification makes no 
sense, since every n-class classification problem can be split into n binary 
classification problems.

When assuming classes 0 and 1, the performance increases and I get to:

cpu time: 608 real time: 605 gc time: 68

For finding the best split.

Daniel's solution makes use of multiple return values, which were new to me. I 
am using a struct for this, which might be unnecessary and later removed in 
favor of returning multiple values like in Daniel's solution.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
On Monday, July 24, 2017 at 11:36:00 PM UTC+2, Daniel Prager wrote:
> Hi Zelphir
> 
> Thanks for the attribution.
> 
> I'm running on a MacBook Air, 2012 vintage.
> 
> Why not run both my and your code on your machine and compare?
> 
> I made no optimisations other than assuming binary classification.
> 
> 
> 
> Dan
> 
> 
> On Tue, Jul 25, 2017 at 6:46 AM, Zelphir Kaltstahl <zelphirk...@gmail.com> 
> wrote:
> 
> 
> 
> 
> With my implementation of a list of vectors I only get down to:
> 
> 
> 
> cpu time: 996 real time: 994 gc time: 52
> 
> 
> 
> on my machine. Now I don't know what kind of machine you have, but I guess 
> with such small data sets it does not matter that much and the list of lists 
> implementation is faster, at least for low dimensional data :) It seems 
> vectors involve a bit of overhead or you did some other optimization, which I 
> still have to add to my code. (Maybe assuming binary class, but that should 
> not make that much of a difference, I think. Might try that soon.)
> 
> 
> 
> I added your code as a new file and added a comment at the top of the file:
> 
> 
> 
> #|
> 
> Attribution:
> 
> 
> 
> This implementation of decision trees in Racket was written by Daniel Prager 
> and
> 
> was originally shared at:
> 
> 
> 
> https://groups.google.com/forum/#!topic/racket-users/cPuTr8lrXCs
> 
> 
> 
> With permission it was added to the project.
> 
> |#
> 
> 
> 
> My project on Github is GPLv3.

Your implementation is more complete than mine, I only got around to fixing the 
things mentioned in this topic, not to implementing all the other stuff still 
waiting for me in the tutorial. As soon as that is done, I can do a comparison. 

Another interesting thing would be to see how many more column (if at all) it 
takes to make vectors the faster implementation.

I also need to take a look at some procedures you used in the code, which I am 
not familiar with yet, but which are standard Racket. There might be clever 
implementations behind those, which are better than what I would write with the 
set of things I know about Racket.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
On Monday, July 24, 2017 at 10:04:36 PM UTC+2, Daniel Prager wrote:
> Jon wrote:
> > Aside: if I read Daniel's solution correct, he avoids the first issue by 
> >assuming that it's a binary classification task (that is, that there are 
> >only two classes).
> 
> 
> Yep: I'm assuming binary classification.
> 
> 
> David wrote:
> > Out of curiosity, how much of that 0.5 seconds is overhead?  Could you run 
> >a simple 'add 1 and 1' procedure and see how long it takes?
> 
> 
> 
> I'm not exactly sure what you mean. Please feel free to profile however you 
> like on the supplied code.
> 
> My observation (primarily to Zelphir) on performance is that lists don't seem 
> like a bad choice for this algorithm.
> 
> If it hadn't been reasonably quick I might have tried replacing the dataset 
> (a list of lists) with a list of vectors, but otherwise I'd be looking at 
> modifying the exhaustive, greedy algorithm itself for possible speedups 
> rather than data structures.
> 
> Zelphir:
> > Maybe you could put it in a repository, so that other people are more 
> >likely to find your code.
> 
> If I ever get back into ML I might, but don't have the time to do a proper 
> write up.
> 
> Please feel free to include it in your github repository, with or without 
> attribution.
> 
> 
> Dan

With my implementation of a list of vectors I only get down to:

cpu time: 996 real time: 994 gc time: 52

on my machine. Now I don't know what kind of machine you have, but I guess with 
such small data sets it does not matter that much and the list of lists 
implementation is faster, at least for low dimensional data :) It seems vectors 
involve a bit of overhead or you did some other optimization, which I still 
have to add to my code. (Maybe assuming binary class, but that should not make 
that much of a difference, I think. Might try that soon.)

I added your code as a new file and added a comment at the top of the file:

#|
Attribution:

This implementation of decision trees in Racket was written by Daniel Prager and
was originally shared at:

https://groups.google.com/forum/#!topic/racket-users/cPuTr8lrXCs

With permission it was added to the project.
|#

My project on Github is GPLv3.



I think I implemented the suggestions made so far in this discussion, except 
memoization of columns. That could be another big time saver.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
On Monday, July 24, 2017 at 6:44:23 PM UTC+2, Matthias Felleisen wrote:
> > On Jul 24, 2017, at 12:37 PM, Zelphir Kaltstahl 
> > <zelphirkaltst...@gmail.com> wrote:
> > 
> > In general I think available libraries are important for creating 
> > attraction to a programming language. For example I like Python's machine 
> > learning and data munging libraries and this is one reason why I frequently 
> > use them. It would be great to have something equally great in Racket, even 
> > if experienced Racket programmers can code something up in a day or two.
> 
> 
> Yes! Develop a package for ML in Racket and people will use it!

I think it will take a long time to get there, but by writing a few algorithms 
and trying to make them uniformly accessible, I think I can get some basis 
going. Will see how far my motivation takes me ;) It is also a learning 
experience for me. I've implemented decision trees and linear regression in 
Python before and some other algorithms half, in some online courses, but I 
think there are many things I did not write yet and still need to even hear 
about.

I'll make all my ML code freely available on Github probably and will see what 
becomes of it.

I don't have any experience with packaging in Racket yet, but I think that is 
something for later, when I actually get some stuff working and the quality of 
code is anything I'd like to show someone. (not like the state the code is in 
right now, with all the issues, which were pointed out!)

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
Already fixed that `class-labels` issue, thanks, it was a quick fix today 
morning. I already tested it with that change and it was way faster.

I thought about going for binary classification only while programming, but I 
think I managed to keep it generic for multiple classes at least in most of the 
code.
Maybe that is not necessary, because every n classes classification problem can 
be expressed with n binary classifications ("in a class or in one of the 
others", for each of the classes).
I think however not assuming 2 classes does not impact performance in this case.

If there are not only binary splits, but three parts split for example, the 
algorithm becomes less efficient.
The reason is, that for each split value, one would have to check again all the 
other split values of a feature and that would be O(n^2), I believe, instead of 
O(n). So maybe not assuming binary splits just makes things harder on myself, 
because no one is going to do three part splits or even more.

Thanks for your suggestions.

@Daniel Prager:

Thanks for posting that code, I might relate to it when getting there. Seems 
concise. Maybe you could put it in a repository, so that other people are more 
likely to find your code.

In general I think available libraries are important for creating attraction to 
a programming language. For example I like Python's machine learning and data 
munging libraries and this is one reason why I frequently use them. It would be 
great to have something equally great in Racket, even if experienced Racket 
programmers can code something up in a day or two.

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
> - Are you running this code inside DrRacket? If so, have you timed the
> difference between running it with debugging enabled and with no
> debugging or profiling? (Language -> Choose Language... -> Details)

I am running from terminal with:

```racket -l errortrace -t FILE``` and
```raco test TESTFILE```

-- 
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] Re: Decision Tree in Racket - Performance

2017-07-24 Thread Zelphir Kaltstahl
Wow, thanks for all the feedback, I'll try to get most of the mentioned stuff 
done and then post an update : )

> I teach trees and decision trees to freshman students who have never 
> programmed before, and Racket’s forms of data and functions are extremely 
> suitable to this domain.

I think this is relating to using vectors and accessing them by index? How 
would you represent the data? What forms of data are better suited?

Mentioned were:

- struct instead of hash
- list of vectors instead of vector of vectors

Your post made me think of functions themselves. Would it be possible to 
represent the splits as chains of functions and would that have any advantage? 
Is that what you are hinting at?

-- 
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] Decision Tree in Racket - Performance

2017-07-23 Thread Zelphir Kaltstahl
Hi Racket Users,

The last few days I've been working on implementing decision trees in Racket 
and I've been following the following guide: 
http://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/

Now I have the following code: https://github.com/ZelphirKaltstahl/racket-ml

I also wrote some tests, I think for every procedure so far.

However, my implementation seems very very slow. It seems each iteration of 
`iter-features` takes way too much time.

I've tried to stick to the guide and sometimes "outsourced" some procedure.

I started out with using vectors, as I thought I might gain better performance 
than from lists. In the code I introduced an abstraction layer, which provides 
things like `data-length`, so that I could in theory change the representation 
of data and only change those accessors/getters. In the test cases I sometimes 
did not use the abstraction though.

So far I am not having much side effects in the code and I'd like to avoid them 
and unsafe operations.

A small `TEST-DATA` set is in the code and another data set I downloaded from 
the data set repositories. When running with `TEST-DATA` to calculate the best 
split, it only takes a few milliseconds, while it takes minutes with the other 
`data-set`.

How can I make my code more efficient, without changing the basic logic of it?
Should I not use vectors (what else?)?
Would I gain anything from using typed Racket or flonums?

-- 
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 and Contracts

2017-07-01 Thread Zelphir Kaltstahl
I tried some simple examples of Typed Racket recently and then I thought I 
could try some things with contracts too.

However, I do not seem to be able to contract-out any Typed Racket struct. For 
example:


~~~
#lang typed/racket

(struct WordMetadata
  ([id : String]
   [learned : Boolean]
   [description : String]))

(provide (contract-out
  [struct WordMetadata
(id string?)
(learned boolean?)
(description string?)]))
~~~


would underline the parenthesis immediately before contract-out, telling me 
that:


~~~
contract-out: not a provide sub-form
~~~


The simple examples in the docs always use:


~~~
#lang racket
~~~


After a lot of wondering what I am doing wrong, I am guessing, that because 
Typed Racket creates its own contracts for the types of the structs, I cannot 
put contracts on them and contract-out does not accept such structs, as opposed 
to structs of #lang racket.

However, I am only guessing. (Is this correct?)

And if if is correct or at least something in that direction, does it even make 
sense to combine Typed Racket with contracts, or am I maybe trying to do 
something which does not really make sense?

-- 
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] Re: how to get full tracebacks in DrRacket?

2017-07-01 Thread Zelphir Kaltstahl
On Friday, June 30, 2017 at 5:10:44 PM UTC+2, Matthew Butterick wrote:
> Is there a way to configure DrRacket so that it always prints the same 
> full-length tracebacks that are visible on the command line? Here's an 
> example of the same module run in both places. 

On command line I usually don't get a full trace unless I invoke with:

~~~
racket -l errortrace -t 
~~~

Does the option in DrRacket do this internally?

-- 
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 Type Annotations - Best Practices?

2017-06-30 Thread Zelphir Kaltstahl
On Friday, June 30, 2017 at 6:59:27 AM UTC+2, johnbclements wrote:
> > On Jun 29, 2017, at 17:33, Zelphir Kaltstahl <zelphirkaltst...@gmail.com> 
> > wrote:
> > 
> > A while ago I started looking at Typed Racket and today I took a look again.
> > 
> > The documentation says:
> > 
> >> Typed Racket provides modified versions of core Racket forms, which permit 
> >> type annotations. Previous versions of Typed Racket provided these with a 
> >> : suffix, but these are now only included as legacy forms for backwards 
> >> compatibility.
> > 
> > To me this sounds as if I am not supposed to use them anymore. So I tried 
> > the following, which works:
> > 
> > ~~~
> > racket -I typed/racket
> > 
> > (let ([x 7.0])
> >  (ann x Positive-Flonum)
> >  x)
> > ~~~
> > 
> > So I could use `ann` instead, but is it not as short as the colon notation.
> > Then I also discovered:
> > 
> > ~~~
> > (let ([x 7.0])
> >  (: x Positive-Flonum)
> >  x)
> > ~~~
> > 
> > Which also works. It is not a change in a core form, so I guess this is not 
> > part of the stuff kept for backward compatibility (?).
> > 
> > I'd like to know what the best practice of writing type annotations is. The 
> > guide in the documentation still uses a lot of the changed core forms, 
> > which is my impression are not recommended, since they're only kept for 
> > backwards compatibility, so one should not rely on them.
> 
> I believe this text is referring to forms such as for: and lambda: — that is, 
> syntactic terms where the lambda is attached to the identifier. I believe 
> this text is *not* referring to the use of the colon as a simple “has-type” 
> form.
> 
> John

Hm that could be it! I was already wondering why it was talking about "suffix" 
instead of "infix". I was assuming it meant suffix because it is after the 
first element of the s-expressions and it was a comment next to where those 
were introduced.

Ok but what is the best practice? Using:

~~~
(ann a Type)
~~~

~~~
(: a Type)
~~~

~~~
(a : Type)
~~~

and when? For example in a let form, I could imagine that it might be best 
practice to specify the type where the variable is specified, instead of a new 
line and a new s-expression.
But I'd like to read some reasoning or guide from someone who knows a lot about 
Typed Racket or maybe even worked on 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.


[racket-users] Typed Racket Type Annotations - Best Practices?

2017-06-29 Thread Zelphir Kaltstahl
A while ago I started looking at Typed Racket and today I took a look again.

The documentation says:

> Typed Racket provides modified versions of core Racket forms, which permit 
> type annotations. Previous versions of Typed Racket provided these with a : 
> suffix, but these are now only included as legacy forms for backwards 
> compatibility.

To me this sounds as if I am not supposed to use them anymore. So I tried the 
following, which works:

~~~
racket -I typed/racket

(let ([x 7.0])
  (ann x Positive-Flonum)
  x)
~~~

So I could use `ann` instead, but is it not as short as the colon notation.
Then I also discovered:

~~~
(let ([x 7.0])
  (: x Positive-Flonum)
  x)
~~~

Which also works. It is not a change in a core form, so I guess this is not 
part of the stuff kept for backward compatibility (?).

I'd like to know what the best practice of writing type annotations is. The 
guide in the documentation still uses a lot of the changed core forms, which is 
my impression are not recommended, since they're only kept for backwards 
compatibility, so one should not rely on them.

-- 
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 Webserver add routes outside of dispatch-rules

2017-06-02 Thread Zelphir Kaltstahl
Thanks again, I think I got how to use it now.

Here is my example:

(define-container main-container (hsk-dispatch a-url))
(dispatch-rules! main-container
 [("") #:method "get" overview-app])
(dispatch-rules! main-container
 [("index") #:method "get" overview-app])
(dispatch-rules! main-container
 [("home") #:method "get" overview-app])
(dispatch-rules! main-container
 [("hsk") #:method "get" hsk-app])

I define a container, for the purpose of later adding dispatch rules to it. 
That is what I do immediately afterwards. That would be no different to what I 
had before with the safe dispatch-rules procedure. However, now I can at any 
time add more rules to the container. Before, I did not define a container, so 
I was not able to add any dispatch rules to anything. Correct?

I could now probably (require ...) the part of Racket's web server which 
(provide ...)s the (dispatch-rules! ...) procedure wherever else in the code I 
need it to add rules dynamically.

However, to refine the process of adding dispatch rules in my code, I'd like to 
do one more thing: I'd like to write a procedure, which looks as follows:

(define (add-route route method proc)
  (dispatch-rules! main-container
   [route #:method method (proc)]))

If I had such a procedure, I could provide that to other modules, which require 
my server module and I would not have to require Racket's web server in these 
other modules.

According to the documentation a dispatch-pattern, which I called "route" in my 
(add-route ...) procedure, is either () or (string . dispatch-pattern) or 
something else. When I define a dispatch rule, I simply put parentheses around 
multiple strings in the call of dispatch-rules. However, when I do that in the 
REPL, it gives an error, because it is not a valid expression on its own.

Now I would like to know how I can pass a dispatch-pattern to a procedure and 
then in that procedure pass it to (dispatch-rules! ...).

-- 
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 Webserver add routes outside of dispatch-rules

2017-06-02 Thread Zelphir Kaltstahl
On Thursday, June 1, 2017 at 10:43:13 PM UTC+2, Jay McCarthy wrote:
> I believe that you want `dispatch-rules!` rather than `dispatch-rules`
> 
> http://docs.racket-lang.org/web-server/dispatch.html?q=dispatch-rules#%28part._.Imperative_.Dispatch_.Containers%29
> 
> This lets you define a container of routes that is used by your
> top-level and then various parts of your application inject their
> URL<->fun mappings into it.
> 
> Jay
> 
> On Tue, May 30, 2017 at 6:47 PM, Zelphir Kaltstahl
> <zelphirkaltst...@gmail.com> wrote:
> > I have the following server specification:
> >
> > (define (start request)
> >   ;; for now only calling the dispatch
> >   ;; we could put some action here, which shall happen before each 
> > dispatching
> >   (hsk-dispatch request))
> >
> > (define-values (hsk-dispatch a-url)
> >   (dispatch-rules [("") #:method "get" overview-app]
> >   [("index") #:method "get" overview-app]
> >   [("home") #:method "get" overview-app]
> >   [("hsk") #:method "get" hsk-app]
> >   [("ajax" "hsk-1-data") #:method "get" hsk-1-data]))
> >
> > (serve/servlet
> >   start
> >   #:servlet-path "/index"  ; default URL
> >   #:extra-files-paths (list (build-path (current-directory) "static"))  ; 
> > directory for static files
> >   #:port 8000 ; the port on which the servlet is running
> >   #:servlet-regexp #rx""
> >   #:launch-browser? false  ; should racket show the servlet running in a 
> > browser upon startup?
> >   ;; #:quit? false  ; ???
> >   #:listen-ip false  ; the server will listen on ALL available IP 
> > addresses, not only on one specified
> >   #:server-root-path (current-directory)
> >   #:file-not-found-responder respond-unknown-file)
> >
> > With some requires of other modules etc.. I am adding routes in the 
> > dispatch-rules part of the program. However, I'd like to add routes and 
> > specify which procedures handle requests to them elsewhere in the program.
> >
> > The reason why I want to do this is, that I want to create a procedure 
> > similar to what I recently saw in Chicken Scheme's web framework Awful:
> >
> > http://wiki.call-cc.org/eggref/4/awful#using-ajax
> >
> > There is a procedure, which generates jQuery code, which is on a web page, 
> > which then requests a route, which I can specify when I call the ajax 
> > procedure.
> >
> > I wonder if (1) and how (2) I could specify routes like that outside of the 
> > dispatch-rules part of the program, so that I could get something like 
> > Awful's ajax procedure (3) or maybe if there even already is such a thing 
> > for Racket's webserver (4).
> >
> > What I like about it is, that I can code everything "on the server side" 
> > and in Racket instead of having to switch to JavaScript at some point and 
> > still I am able to "connect" parts of the actual DOM elements to procedures 
> > on the server side. Without such a thing, it might be better to let the 
> > server send only raw data and handle all DOM tree logic in JavaScript in a 
> > static JavaScript file, because that way, I'd have knowledge about the DOM 
> > elements in the code, because I'd be creating them in JavaScript on the 
> > basis of that raw knowledge. On the other hand, if I render some HTML on 
> > the server side and send it to the client and the client needs to modify it 
> > and inform the server about it, I'll have to rely on certain ids and 
> > classes of DOM elements simply being there, while I had to switch context 
> > to JavaScript. This feels less clean than either generating all DOM 
> > elements in JavaScript code or generating everything with a procedure like 
> > Awful's ajax procedure.
> >
> > I don't need much, probably only a few click listeners, so maybe my 
> > procedure could be less complex than the ajax of Awful. Or since Racket is 
> > very similar in Syntax, I could try to copy most of the code.
> >
> > For another utf8 related reason, I cannot use Chicken Scheme at the moment, 
> > so I reimplemented everything in Racket, where I do not have that problem, 
> > but also do not know of any such ajax procedure.
> >
> > --
> > 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 
&

[racket-users] Racket Webserver add routes outside of dispatch-rules

2017-05-30 Thread Zelphir Kaltstahl
I have the following server specification:

(define (start request)
  ;; for now only calling the dispatch
  ;; we could put some action here, which shall happen before each dispatching
  (hsk-dispatch request))

(define-values (hsk-dispatch a-url)
  (dispatch-rules [("") #:method "get" overview-app]
  [("index") #:method "get" overview-app]
  [("home") #:method "get" overview-app]
  [("hsk") #:method "get" hsk-app]
  [("ajax" "hsk-1-data") #:method "get" hsk-1-data]))

(serve/servlet
  start
  #:servlet-path "/index"  ; default URL
  #:extra-files-paths (list (build-path (current-directory) "static"))  ; 
directory for static files
  #:port 8000 ; the port on which the servlet is running
  #:servlet-regexp #rx""
  #:launch-browser? false  ; should racket show the servlet running in a 
browser upon startup?
  ;; #:quit? false  ; ???
  #:listen-ip false  ; the server will listen on ALL available IP addresses, 
not only on one specified
  #:server-root-path (current-directory)
  #:file-not-found-responder respond-unknown-file)

With some requires of other modules etc.. I am adding routes in the 
dispatch-rules part of the program. However, I'd like to add routes and specify 
which procedures handle requests to them elsewhere in the program.

The reason why I want to do this is, that I want to create a procedure similar 
to what I recently saw in Chicken Scheme's web framework Awful:

http://wiki.call-cc.org/eggref/4/awful#using-ajax

There is a procedure, which generates jQuery code, which is on a web page, 
which then requests a route, which I can specify when I call the ajax procedure.

I wonder if (1) and how (2) I could specify routes like that outside of the 
dispatch-rules part of the program, so that I could get something like Awful's 
ajax procedure (3) or maybe if there even already is such a thing for Racket's 
webserver (4).

What I like about it is, that I can code everything "on the server side" and in 
Racket instead of having to switch to JavaScript at some point and still I am 
able to "connect" parts of the actual DOM elements to procedures on the server 
side. Without such a thing, it might be better to let the server send only raw 
data and handle all DOM tree logic in JavaScript in a static JavaScript file, 
because that way, I'd have knowledge about the DOM elements in the code, 
because I'd be creating them in JavaScript on the basis of that raw knowledge. 
On the other hand, if I render some HTML on the server side and send it to the 
client and the client needs to modify it and inform the server about it, I'll 
have to rely on certain ids and classes of DOM elements simply being there, 
while I had to switch context to JavaScript. This feels less clean than either 
generating all DOM elements in JavaScript code or generating everything with a 
procedure like Awful's ajax procedure.

I don't need much, probably only a few click listeners, so maybe my procedure 
could be less complex than the ajax of Awful. Or since Racket is very similar 
in Syntax, I could try to copy most of the code.

For another utf8 related reason, I cannot use Chicken Scheme at the moment, so 
I reimplemented everything in Racket, where I do not have that problem, but 
also do not know of any such ajax procedure.

-- 
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] How to pretty print HTML?

2017-05-28 Thread Zelphir Kaltstahl
On Sunday, May 28, 2017 at 10:20:10 PM UTC+2, Matthias Felleisen wrote:
> I have the impression that you are conflating rendering as an output with 
> representing as a string. So the following code tries to sketch this: 
> 
> (require xml)
> 
> ;; Xexpr -> String 
> (define (xexpr->xml/pretty x) 
>   (with-output-to-string
>(lambda ()
>  (display-xml/content
>   (xexpr->xml x)
> 
> (define x
>   `(html
> (body ((bgcolor "red"))
>   "Hi!" (br) "Bye!")))
> 
> (xexpr->xml/pretty x) ;; turn XML into string with newlines and indentation 
> and all — but see how the IDE renders it in the REPL 
> 
> (displayln (xexpr->xml/pretty x)) ;; print the same string — now the IDE is 
> forced to render the printed output 
> 
> — Matthias
> 
> 
> 
> 
> > On May 28, 2017, at 7:55 AM, Zelphir Kaltstahl <zelphirkaltst...@gmail.com> 
> > wrote:
> > 
> > I have some HTML code, which I generate using x-expressions:
> > 
> > (string-append DOCTYPE-HTML5
> >   "\n"
> >   (xexpr->string
> >`(html
> >  (body ((bgcolor "red"))
> >"Hi!" (br) "Bye!"
> > 
> > I don't like how the result looks in the source code of the web page 
> > created in this way. I'd like there to be indentation and line breaks, 
> > according to the nesting of the DOM elements.
> > 
> > So far I've found the following links and information:
> > 
> > - https://docs.racket-lang.org/reference/pretty-print.html (I don't know 
> > how to use it, because it has no examples. It also seems more like a 
> > library, which generically can pretty print anything you want, provided you 
> > "configure" is correctly. However, HTML is quite complex, I think, so I'd 
> > not like to rewrite something that already exists elsewhere.)
> > - https://docs.racket-lang.org/xml/ (Here are some mentions of indentation 
> > and newlines, but I need some procedure, which returns it, not displays it 
> > immediately and then "does not let me have it", or is there a way to 
> > somehow redirect output into a value which I can use? For example 
> > `display-xml` seems to do what I need. :)
> > 
> > Ideal might be a keyword parameter for `xexpr->string`, which specifies 
> > whether it should prettify the string or not, but such a thing does not 
> > exist according to the docs.
> > 
> > How can I prettify my HTML output?
> > 
> > (I really don't care about a few bytes more data needing to be sent. This 
> > is not the next Google.)
> > 
> > -- 
> > 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.

Perfect! Does exactly what I wanted.

It is only that I care how it looks when I open the source code view of a web 
page and all the HTML was on one super long line. I know it does not make a 
difference for how the browser renders things, but it is somewhat annoying for 
myself to know that it is not properly indented etc. in the source of the HTML 
page.

I did not know about `with-output-to-string` - This means I can get any output 
of a procedure, which usually prints that right away, into a string, I guess.

Thanks for your help.

-- 
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] Bug in table-panel% ?

2017-04-24 Thread Zelphir Kaltstahl
Yep, that workaround seems to work, thank you.

I did not know about issues when deleting and adding children in an already 
shown widget/window. It's good to be aware, that such can make a difference.

I noticed now, that although the GUI is still very fast, still being very 
small, it flickers a little bit, when I switch between the tab panel's tabs, 
because I am deleting children and creating new ones to take their place. In 
the future, the children widgets in the tab panel are supposed to show some 
data. I am not sure how to avoid recreating them, as they grow larger in 
dimensions and content and the flickering might increase.

Maybe I am going about this updating widgets the wrong way, recreating them, 
instead of somehow changing their content. I'll observe this and maybe ask in a 
new post if necessary.

Thanks for your help!
I find the code for GUI in Racket to be quite elegant, compared to what I am 
used to in GUI libraries. It takes a little time to get used to the way how 
parent and child elements are handled, but so far it is great. Might be a few 
more widgets or containers would be nice to have in the standard library, for 
example the table-panel if it was working as well as the other widgets. 
However, so far I could find all I need.

-- 
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] Bug in table-panel% ?

2017-04-23 Thread Zelphir Kaltstahl
I am creating a little hobby project with Racket GUI classes. For that I got 
the following code, which creates a frame%:

#lang racket/gui

(require table-panel
 "vocabulary.rkt")
(provide build-gui)


(define (clear-children an-area-container)
  (for ([child (send an-area-container get-children)])
(send an-area-container delete-child child)))


(define (build-gui)
  ; Make a frame by instantiating the frame% class
  (define frame (new frame%
 [label "Example"]
 [alignment (list 'center 'center)]
 [min-width 320]
 [min-height 240]))
  (define tab-panel (new tab-panel%
 [parent frame]
 [choices (map (lambda (voc) (get-vocabulary-identifier 
voc))
   VOCABULARY)]
 [callback
  (lambda (widget event)
(let* ([tab-selection-index (send tab-panel
  get-selection)]
   [tab-label (send tab-panel
get-item-label
tab-selection-index)])
  (set-tab-panel-content tab-panel tab-label)))]))
  (define (set-tab-panel-content a-tab-panel a-label)
(clear-children a-tab-panel)
(define progress
  (exact-floor
   (* 100
  (get-vocabulary-learn-progress
   (first (get-vocabularies-by-identifier a-label))
(define progress-gauge
  (new gauge%
   [label (string-append "Progress (" (number->string (/ progress 
100.0)) "%): ")]
   [range 1]
   [parent a-tab-panel]
   [min-width 100]))
(define table-panel
  (new table-panel%
  [parent tab-panel]
  [alignment '(center center)]
  [dimensions '(4 2)]))
(define (initialize-widgets)
  (send progress-gauge set-value progress)
  (for ((i (in-range 4)))
(let ([child-table (new table-panel%
[parent table-panel]
[style '(border)]
[dimensions (list 4 3)]
[column-stretchability (if (memq i '(0 1)) #t 
#f)]
[row-stretchability (if (memq i '(0 2)) #t 
#f)])])
  (for ([label-string (list "1" "2" "3"
"4" "5" "6"
"7" "8" "9"
"*" "0" "#")])
(new button%
 [parent child-table]
 [label label-string]
 [stretchable-width #t]
 [stretchable-height #t]
 [callback
  (lambda (button event)
(displayln (send button get-label)))])
(initialize-widgets))

  (define (set-initial-gui-state)
(set-tab-panel-content tab-panel
   (send tab-panel get-item-label 0)))

  ;; initialize things
  (set-initial-gui-state)

  ;; return the frame
  frame)

When I `show` this frame using:

(send frame show true)

It at first renders the table-panel fine, but when I switch the tabs in the 
tab-panel, I get weird errors:

compute-sizes: undefined;
 cannot use field before initialization
  context...:
   /home/xiaolong/.racket/6.8/pkgs/table-panel/main.rkt:340:4: container-size 
method in table-panel%
   /usr/share/racket/collects/racket/private/more-scheme.rkt:148:2: 
call-with-break-parameterization
   /usr/share/racket/pkgs/gui-lib/mred/private/wxcontainer.rkt:20:31: 
get-graphical-min-size method in ...vate/wxcontainer.rkt:13:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:347:8: get-min-size 
method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxitem.rkt:155:10: get-info 
method in ...d/private/wxitem.rkt:34:6
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:255:8: 
get-children-info method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxcontainer.rkt:20:31: 
get-graphical-min-size method in ...vate/wxcontainer.rkt:13:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:347:8: get-min-size 
method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxitem.rkt:155:10: get-info 
method in ...d/private/wxitem.rkt:34:6
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:255:8: 
get-children-info method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:287:8: 
do-graphical-size method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxpanel.rkt:347:8: get-min-size 
method in .../private/wxpanel.rkt:71:4
   /usr/share/racket/pkgs/gui-lib/mred/private/wxitem.rkt:155:10: get-info 
method in 

Re: [racket-users] Errors in url dispatch of static files

2017-03-28 Thread Zelphir Kaltstahl
I seem to have a similar problem with the dispatch of static files. I posted it 
on Stackoverflow. Could you take a look at it?

https://stackoverflow.com/questions/43027717/racket-servlet-serve-static-files

-- 
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.