Re: [racket-users] Performance for structs across typed–untyped boundaries

2018-09-17 Thread Ben Greenman
Your program is half an answer :) Here's a second half to compare:

#lang racket/base

(module typed1 typed/racket/base
  (provide (struct-out container)
   container-append)
  (define-type SymbolTree
(U Null Symbol (Pairof SymbolTree SymbolTree)))
  (struct container ([tree : SymbolTree])
#:transparent)
  (: container-append (-> container container container))
  (define (container-append a b)
(container (cons (container-tree a)
 (container-tree b)

(module typed2 typed/racket/base
  (provide container
   container-append)
  (define-type SymbolTree
(U Null Symbol (Pairof SymbolTree SymbolTree)))
  (define-type container2 (Pairof 'container SymbolTree))
  (define (container (tree : SymbolTree)) : container2
(cons 'container tree))
  (define (container-tree (c : container2)) : SymbolTree
(cdr c))
  (: container-append (-> container2 container2 container2))
  (define (container-append a b)
(container (cons (container-tree a)
 (container-tree b)

(require
  (prefix-in struct: 'typed1)
  (prefix-in list: 'typed2))

(for ((iters (in-range 1 6)))
  (for ((make-c (in-list (list struct:container list:container)))
(c-append (in-list (list struct:container-append
list:container-append)))
(name (in-list '("struct" "list"
(define n (* iters 10))
(printf "testing ~a (~a iters)~n" name n)
(time
  (for/fold ((acc (make-c '(
((_i (in-range n)))
(c-append acc (make-c (build-list (expt 10 4) (lambda (_) 'X

The version with lists runs much slower for me than the one with structs:

testing struct (10 iters)
cpu time: 1493 real time: 1509 gc time: 6
testing list (10 iters)
cpu time: 9775 real time: 9885 gc time: 9
testing struct (20 iters)
cpu time: 3031 real time: 3107 gc time: 4
testing list (20 iters)
cpu time: 34468 real time: 34796 gc time: 57


In general (iiuc): since Typed Racket defined this non-prefab
non-polymorphic struct, it can trust the fields of a `container?`
value.

> Assuming the answer to this question isn't likely to change, I think it would 
> be worth adding to the documentation, perhaps at 
> http://docs.racket-lang.org/ts-guide/typed-untyped-interaction.html#%28part._.Protecting_.Typed-.Untyped_.Interaction%29
>  or 
> http://docs.racket-lang.org/ts-guide/optimization.html#%28part._contract-costs%29.
>  For the use-case I'm considering, having to traverse the entire data 
> structure on typed–untyped boundary crossings would clearly be prohibitive.

Yes good 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.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Performance for structs across typed–untyped boundaries

2018-09-17 Thread Philip McGrath
I have a fairly basic question about what checking is done when instances
of structs defined in Typed Racket cross typed–untyped boundaries.

For a concrete example, in the following program, I'm interested in the
call to `container-append` from untyped code:

#lang racket/base

(module typed typed/racket/base
  (provide (struct-out container)
   container-append)
  (define-type SymbolTree
(U Null Symbol (Pairof SymbolTree SymbolTree)))
  (struct container ([tree : SymbolTree])
#:transparent)
  (: container-append (-> container container container))
  (define (container-append a b)
(container (cons (container-tree a)
 (container-tree b)

(require 'typed)

(container-append (container '(a b c))
  (container '(d e f)))

My hope is that, since `container` is defined in Typed Racket, the contract
generated for `container-append` would only need to check that its
arguments satisfy `container?`: it could rely on the `container`
constructor to assure that the fields have the right types.

I want to know for certain, though, because it seems at least possible that
it might not be sound to assume that `container` instances are valid
(perhaps because of reflective operations or something), in which case the
generated contract would need to traverse the entire data structure. This
would change the complexity of a function like `container-append`.

Assuming the answer to this question isn't likely to change, I think it
would be worth adding to the documentation, perhaps at
http://docs.racket-lang.org/ts-guide/typed-untyped-interaction.html#%28part._.Protecting_.Typed-.Untyped_.Interaction%29
or
http://docs.racket-lang.org/ts-guide/optimization.html#%28part._contract-costs%29.
For the use-case I'm considering, having to traverse the entire data
structure on typed–untyped boundary crossings would clearly be prohibitive.

-Philip

-- 
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 Users] Macros and literals question

2018-09-17 Thread Matthew Butterick

> On Sep 17, 2018, at 11:57 AM, Kevin Forchione  wrote:
> 
> In a nutshell I’m working with some hash tables whose keys are symbol and 
> whose values may be other keys or values such as identifiers, and I got a bit 
> tired of quoting all my symbols for functions and decided to use some macros 
> when working with the tables.

OK. Yes, in general you need a macro to convert something like `(id bar)` to 
`(other-id 'bar)`, because otherwise the naked `bar` is treated as an 
identifier (and therefore as usual needs a binding, or the program won't run). 
For even more notational convenience, you might also look at the `read-cdot` 
parameter and `#%dot` identifier, which can expand `table.key` to something 
like `(hash-ref table 'key)`.

-- 
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 Users] Macros and literals question

2018-09-17 Thread Kevin Forchione


> On Sep 16, 2018, at 10:07 PM, Matthew Butterick  wrote:
> 
> 
>> On Sep 16, 2018, at 2:13 PM, Kevin Forchione > > wrote:
>> 
>> Thanks! That’s just what I wanted. Is there a way in Racket to determine if 
>> a quoted symbol has an associated procedure? 
> 
> 
> 
> #lang racket
> (require rackunit)
> 
> (define-syntax (bound-to-proc? stx)
>   (syntax-case stx ()
> [(_ 'x)
>  (and (identifier? #'x) (identifier-binding #'x))
>  #'(procedure? x)]
> [_ #'#f]))
> 
> (define bound-to-proc +)
> (define not-bound-to-proc 42)
> 
> (check-true (bound-to-proc? 'bound-to-proc))
> (check-false (bound-to-proc? 'not-bound-to-proc))

Sorry for the typo and thanks for the further explanation. Your original 
response to my query was more in line with what I’m trying to accomplish, while 
my second question was more in the realm of  curiosity. In a nutshell I’m 
working with some hash tables whose keys are symbol and whose values may be 
other keys or values such as identifiers, and I got a bit tired of quoting all 
my symbols for functions and decided to use some macros when working with the 
tables. Probably more than curiosity as I can foresee a need to retrieve a 
value from a table and either apply it, which means somehow getting at the 
binding. 

Kevin

-- 
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 Users] Macros and literals question

2018-09-17 Thread Alexis King
> On Sep 17, 2018, at 12:21, Kevin Forchione  wrote:
> 
> That seems to be the nature of macros, and I’m not sure what the solution to 
> that paradox is, apart from perhaps building a symbol/function hash table as 
> part of a define. Presumably Racke does something like that for eva & 
> namespaces, but I’m surprised there isn’t a symbol->procedure function. 

In general, I think Philip has hit the nail on the head. I, too, thought of 
other Lisp systems when you used the wording “associated procedure” for a 
symbol, and I agree that concept makes less sense in Racket. In a more 
traditional Lisp, symbols themselves are rich values with lots of information 
attached to them, but Racket follows the Scheme approach, which treats symbols 
as nothing more than interned strings. They are just names, not bindings.

To elaborate a little more on this, it might make sense to think of the 
“associated procedure” for a symbol in Common Lisp, but in Racket, that 
information is stored in a separate place: namespaces. A Racket namespace 
represents an environment, and it maps names to values. At runtime, if you want 
to get the value bound to a particular symbol in a given namespace, you can use 
namespace-variable-value[1], but there are some caveats to that.

As mentioned above, in Common Lisp, a package-qualified symbol is precise, but 
a Racket symbol is only meaningful in context. This means that the symbol 'foo 
might be mapped to one thing in one namespace but something completely 
different in another namespace. This is a philosophically different approach to 
binding, but the practical takeaway is that you need to be really careful to 
use the *right* namespace if you want to use namespaces in Racket. A namespace 
can be created that corresponds to the top-level of a module, using 
module->namespace, or it can be an entirely independent, “free-floating” 
top-level environment created with make-base-namespace. You can acquire a 
namespace that corresponds to the surrounding lexical environment using 
define-namespace-anchor[2] and namespace-anchor->namespace[3] or 
#%variable-reference[4] and variable-reference->namespace[5].

However, beware! As Philip alludes to, namespaces only include top-level or 
module-level bindings, *not* local bindings! Racket provides no reflective 
capabilities to inspect local bindings (at least not in general; you could 
theoretically write a #lang that implements this capability yourself). These 
are opaque, and indeed, the Racket compiler does not maintain information about 
the structure of local bindings.

To summarize: Racket is a relatively static language relative to other Lisps, 
and even to other Schemes. The language is entirely {lexically, statically} 
bound. It provides limited reflective capabilities to manipulate top-level 
namespaces and inspect module-level bindings, but no more. There are definitely 
various advantages to this (e.g. local reasoning, encapsulation, optimization), 
but you may need to think differently about Racket’s binding model if coming 
from other Lisp systems.

Alexis

[1]: 
http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28quote._~23~25kernel%29._namespace-variable-value%29%29
[2]: 
http://docs.racket-lang.org/reference/Namespaces.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-namespace-anchor%29%29
[3]: 
http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._namespace-anchor-~3enamespace%29%29
[4]: 
http://docs.racket-lang.org/reference/Locationsvariable-reference.html#%28form._%28%28quote._~23~25kernel%29._~23~25variable-reference%29%29
[5]: 
http://docs.racket-lang.org/reference/Namespaces.html#%28def._%28%28quote._~23~25kernel%29._variable-reference-~3enamespace%29%29

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [Racket Users] Macros and literals question

2018-09-17 Thread Matthew Butterick

> On Sep 17, 2018, at 10:21 AM, Kevin Forchione  wrote:
> 
> That seems to be the nature of macros, and I’m not sure what the solution to 
> that paradox is, apart from perhaps building a symbol/function hash table as 
> part of a define. Presumably Racke does something like that for eva & 
> namespaces, but I’m surprised there isn’t a symbol->procedure function. 


I take a question as I find it, even if its necessity is not clear to me ;) It 
seems a teeny bit possible that you're moving against the grain of how 
identifiers & bindings usually work, and thus certain aspects seem more 
complicated than they need to. 

-- 
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 Users] Macros and literals question

2018-09-17 Thread Philip McGrath
It might help to know a bit more context about what you're trying to do.

I think other Lisp-family languages use these terms in different ways, but
in Racket it isn't usual to talk about a symbol being bound to something. A
symbol is just a type of value (like an integer, a list, a vector, a
function, or anything else) and exists only at the run-time of some code.
Binding, on the other hand, is a compile-time notion. Functions like
`identifier-binding` operate on identifiers, which are syntax objects that
wrap symbols together with lexical context and source-location information:
in other words, the first argument to `identifier-binding` must satisfy
`identifier?`, which means it will never satisfy `symbol?`. Given renaming,
lexical scope, and other features, a symbol isn't enough information to
specify a binding, and I believe that at run-time symbolic names go away
and are replaced by some form of de Bruijn indexes. (Take that last part
with a grain of salt: I don't spend much time with low-level runtime
details.) Also, in `#lang racket`, given that there isn't a static type
system, the question of whether an identifier is bound to a procedure isn't
answerable at compile-time: Matthew's macro thus expands to false for
unbound identifiers, but expands to a `procedure?` check at runtime for all
bound identifiers.

At the same time, if you explain what you are trying to do at a
higher-level, there very well may be a way to do it that involves
implementation techniques you wouldn't think to ask about. For example, if
you want unbound identifiers to be self-quoting as symbols, the answer
would involve defining a macro named `#%top`.

Finally, I'm not sure that I understand your example:

> [define [foo symbols) (bound-to-proc? sum))
>
Ignoring the mismatched parentheses, this use of `bound-to-proc?` doesn't
match the first clause of Matthew's `syntax-case` because there is no
`quote`, and it looks like Matthew tried to implement your request to
determine "if a quoted symbol has an associated procedure".

(The implementation of `bound-to-proc?` would be more robust if
`syntax-case` were given `quote` as a literal, but that way lies madness:
what about `quasiquote`, or macros you don't know about that expand to
symbols? Using `local-expand` could help … but, again, the best thing would
be to know more about what you're ultimately trying to do.)

-Philip


On Mon, Sep 17, 2018 at 12:21 PM Kevin Forchione  wrote:

>
>
> On Sep 16, 2018, at 10:07 PM, Matthew Butterick  wrote:
>
> #lang racket
> (require rackunit)
>
> (define-syntax (bound-to-proc? stx)
>   (syntax-case stx ()
> [(_ 'x)
>  (and (identifier? #'x) (identifier-binding #'x))
>  #'(procedure? x)]
> [_ #'#f]))
>
> (define bound-to-proc +)
> (define not-bound-to-proc 42)
>
> (check-true (bound-to-proc? 'bound-to-proc))
> (check-false (bound-to-proc? 'not-bound-to-proc))
>
>
> Thanks, Matthew. This approach works as long as the macro is being used
> outside of a definition, but I suspect to build any sort of logic around it
> they’d have to be macros as well. For instance, this fails because the
> macro captures symptoms and not the value passed to the function:
>
> [define [foo symbols) (bound-to-proc? sum))
>
> That seems to be the nature of macros, and I’m not sure what the solution
> to that paradox is, apart from perhaps building a symbol/function hash
> table as part of a define. Presumably Racke does something like that for
> eva & namespaces, but I’m surprised there isn’t a symbol->procedure
> function.
>
> Kevin
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] [Racket Users] Macros and literals question

2018-09-17 Thread Kevin Forchione


> On Sep 16, 2018, at 10:07 PM, Matthew Butterick  wrote:
> 
> #lang racket
> (require rackunit)
> 
> (define-syntax (bound-to-proc? stx)
>   (syntax-case stx ()
> [(_ 'x)
>  (and (identifier? #'x) (identifier-binding #'x))
>  #'(procedure? x)]
> [_ #'#f]))
> 
> (define bound-to-proc +)
> (define not-bound-to-proc 42)
> 
> (check-true (bound-to-proc? 'bound-to-proc))
> (check-false (bound-to-proc? 'not-bound-to-proc))

Thanks, Matthew. This approach works as long as the macro is being used outside 
of a definition, but I suspect to build any sort of logic around it they’d have 
to be macros as well. For instance, this fails because the macro captures 
symptoms and not the value passed to the function:

[define [foo symbols) (bound-to-proc? sum)) 

That seems to be the nature of macros, and I’m not sure what the solution to 
that paradox is, apart from perhaps building a symbol/function hash table as 
part of a define. Presumably Racke does something like that for eva & 
namespaces, but I’m surprised there isn’t a symbol->procedure function. 

Kevin

-- 
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] Fun with Physics: Racket FFI Question (Bug?)

2018-09-17 Thread Matthew Flatt
At Mon, 17 Sep 2018 09:34:46 -0700 (PDT), Stephen Foster wrote:
> But when I have two bodies that share the same velocity_func, I get a 
> segfault:

The problem is that a callback is retained (by default) as long as the
function that it wraps is retained, but only a single callback is
retained for a given function. So, creating a second callback loses the
link between the function and the first callback, and the first
callback can be is reclaimed by the GC.

This is often a difficult problem to solve.

> *Things that didn't work*
> 
> 1) Wrapping the function f in separate lambdas still gives a segfault:
> 
> (set-cpBody-velocity_func! (chipmunk-body body1)
>(lambda(b g d dt)
>  (f b d g dt)))
> 
> (set-cpBody-velocity_func! (chipmunk-body body2)
>(lambda(b g d dt)
>  (f b d g dt)))

This change makes things slightly worse, because nothing retains either
of those individual lambdas.

> 2) Storing a reference to the function f in a stab-in-the-dark attempt to 
> "trick the system" or "prevent some kind of mysterious garbage collection" 
> still segfaults:
> 
> (define probably-silly
>   (list
> (lambda(b g d dt)
>   (f b d g dt))
> (lambda(b g d dt)
>   (f b d g dt
> 
> (set-cpBody-velocity_func! (chipmunk-body body1)
>(list-ref probably-silly 0))
> 
> (set-cpBody-velocity_func! (chipmunk-body body2)
>(list-ref probably-silly 1))

Honestly, I'm not clear on why this fails. The `probably-silly` list
should be retained via the module's namespace, and so both of those
`lambda`s should be preserved, and so both callbacks should be
preserved. I'm stumped.


> 3) Storing the function f in two separate variables also segfaults:
> 
> (define (f body gravity damping dt)
>   (ffi:cpointer-push-tag! body 'cpBody)
>   (cpBodySetVelocity body (cpv 0 -10))
> 
>   ffi:_void)
> 
> (define f2 f)

This does nothing, since `f` and `f2` refer to the same value.


> *Things that do work but feel dumb*
> 
> 1) Explicitly duplicating the function verbatim:
> 
> (define (f body gravity damping dt)
>   (ffi:cpointer-push-tag! body 'cpBody)
>   (cpBodySetVelocity body (cpv 0 -10))
> 
>   ffi:_void)
> 
> (define (f2 body gravity damping dt)
>   (ffi:cpointer-push-tag! body 'cpBody)
>   (cpBodySetVelocity body (cpv 0 -10))
> 
>   ffi:_void)
> 
> (set-cpBody-velocity_func! (chipmunk-body body1)
>f)
> 
> (set-cpBody-velocity_func! (chipmunk-body body2)
>f2)

This works because each callbacks is associated to a separate function,
and the separate functions are retained through the module's namespace.

> 2) Duplicating the function with a macro lets me generalize the above 
> workaround for more than two bodies, but it still feels gross.

Yes.


> If someone has an explanation or a better workaround, that would be great.  

Use `#:keep` in the `_fun` for the velocity callback.

To tie the callback's lifetime to the enclosing record, you can
probably use a weak hashtable mapping `cpBody` pointers to callbacks:

  (define callbacks (make-weak-hasheq))
  (define current-cpBody (make-parameter #f))

  (define _cpBodyVelocityFunc
 (_fun #:keep (lambda (cb) (hash-set! callbacks (current-cpBody) cb))
   _pointer _cpVect _cpFloat _cpFloat -> _void))
  
where `current-cpBody` is a way of communicating the record where the
pointer is being stored:

  (let ([body (chipmunk-body body1)])
(parameterize ([current-cpBody body]))
  (set-cpBody-velocity_func! body
  f))

Beware that `callbacks` ties the callback to a cpointer record, not to
the actual pointer value. Since `chipmunk-body` returns the same
Cpointer every time for a given `chipmunk` Racket structure, I think
that's ok --- but it won't be ok if you get the same body pointer from
Chipmunk (via the FFI) multiple times.

-- 
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] Fun with Physics: Racket FFI Question (Bug?)

2018-09-17 Thread Stephen Foster
I'm trying to get the Chipmunk Physics library integrated with Racket.  
I've made some progress (https://www.youtube.com/watch?v=GjvLaP7I0gg), but 
I need to ask for some input on an issue.

The Chipmunk C library provides a primitive called a "cpBody" (i.e. a 
moving thing).  A cpBody struct has a velocity_func pointer which allows 
customization of how the body's velocity is updated during the simulation.

I have noticed odd behavior with these function pointers.  Perhaps this is 
a bug with the FFI?  Perhaps it's perfectly normal and I just don't 
understand something about the FFI?

In any event, when I have one body, this works:

(define body1
  (box 25 5 (cpv 25.0 80.0)
   #:mass 10
   #:meta 'green))

(define (f body gravity damping dt)
  (ffi:cpointer-push-tag! body 'cpBody)
  (cpBodySetVelocity body (cpv 0 -10))

  ffi:_void)

(set-cpBody-velocity_func! (chipmunk-body body1)
   f)


But when I have two bodies that share the same velocity_func, I get a 
segfault:

(define body1
  (box 25 5 (cpv 25.0 80.0)
   #:mass 10
   #:meta 'green))

(define body2
  (box 25 5 (cpv 50.0 80.0)
   #:mass 10
   #:meta 'blue))


(define (f body gravity damping dt)
  (ffi:cpointer-push-tag! body 'cpBody)
  (cpBodySetVelocity body (cpv 0 -10))

  ffi:_void)

(set-cpBody-velocity_func! (chipmunk-body body1)
   f)

(set-cpBody-velocity_func! (chipmunk-body body2)
   f)


I've tried various ways to work around this issue.  But all of them either 
didn't work or feel dumb.


*Things that didn't work*

1) Wrapping the function f in separate lambdas still gives a segfault:

(set-cpBody-velocity_func! (chipmunk-body body1)
   (lambda(b g d dt)
 (f b d g dt)))

(set-cpBody-velocity_func! (chipmunk-body body2)
   (lambda(b g d dt)
 (f b d g dt)))


2) Storing a reference to the function f in a stab-in-the-dark attempt to 
"trick the system" or "prevent some kind of mysterious garbage collection" 
still segfaults:

(define probably-silly
  (list
(lambda(b g d dt)
  (f b d g dt))
(lambda(b g d dt)
  (f b d g dt

(set-cpBody-velocity_func! (chipmunk-body body1)
   (list-ref probably-silly 0))

(set-cpBody-velocity_func! (chipmunk-body body2)
   (list-ref probably-silly 1))

3) Storing the function f in two separate variables also segfaults:

(define (f body gravity damping dt)
  (ffi:cpointer-push-tag! body 'cpBody)
  (cpBodySetVelocity body (cpv 0 -10))

  ffi:_void)

(define f2 f)

(set-cpBody-velocity_func! (chipmunk-body body1)
   f)

(set-cpBody-velocity_func! (chipmunk-body body2)
   f2)



*Things that do work but feel dumb*

1) Explicitly duplicating the function verbatim:

(define (f body gravity damping dt)
  (ffi:cpointer-push-tag! body 'cpBody)
  (cpBodySetVelocity body (cpv 0 -10))

  ffi:_void)

(define (f2 body gravity damping dt)
  (ffi:cpointer-push-tag! body 'cpBody)
  (cpBodySetVelocity body (cpv 0 -10))

  ffi:_void)

(set-cpBody-velocity_func! (chipmunk-body body1)
   f)

(set-cpBody-velocity_func! (chipmunk-body body2)
   f2)

2) Duplicating the function with a macro lets me generalize the above 
workaround for more than two bodies, but it still feels gross.  I know the 
macro could be improved, but that isn't really the point.  The fact that I 
have to know how many  functions to make at compile time is gross.

;The stupid macro
(define-syntax-rule (dumb-duplicate id body)
  (define id
(list
 body
 body
 body
 body
 body)))

(dumb-duplicate fs
(lambda (body gravity damping dt)
  (f body gravity damping dt)))

(set-cpBody-velocity_func! (chipmunk-body body1)
   (list-ref fs 0))

(set-cpBody-velocity_func! (chipmunk-body body2)
   (list-ref fs 1))


That's all I have.  To sum up, sharing the same function pointer across two 
cpBodies seems to segfault to matter what clever tricks I try.  Using 
functions with distinct compile-time source locations does work, but it 
makes me feel icky.  I would prefer to construct the functions I need 
dynamically rather than statically.  In simulations where objects are 
created at runtime, it feels sillier and sillier to have to know beforehand 
how many objects there will be at runtime.

If someone has an explanation or a better workaround, that would be great.  
I'm assuming there's something about the Racket FFI that I haven't learned 
yet.  However, if others are as mystified as I am, I'll assume it's a 
Chipmunk issue, and I'll ask about it over on the Chipmunk forums.  


*Appendix A*

Below is a full program with some rendering, just for context.

It uses this newborn git repo for 

Re: [racket-users] specialized languages

2018-09-17 Thread 'Paulo Matos' via Racket Users
If I understand correctly you want to create languages in Racket?

In which case you want to read:
https://beautifulracket.com/

Paulo Matos

On 17/09/2018 02:22, Hendrik Boom wrote:
> I'm looking for an introduction to the tools for making Racket into a 
> specualized language.
> 
> I know how to write compilers already.  I've done a few for significant 
> languages.
> 
> I'm looking for how to use the specialised tools available in Racket.
> 
> -- hendrik
> 

-- 
Paulo Matos

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.