Common Lisp CFFI: Assign a struct value to an array index - common-lisp

How can I assign the value of an index of a foreign array to be the value of a foreign struct. For example, the following:
(cffi:with-foreign-objects ((x '(:struct my-struct))
(arr '(:struct my-struct) 2))
(setf (cffi:mem-aref arr '(:struct my-struct) 0)
(cffi:mem-ref x '(:struct my-struct))))
Which I expected to be equivalent roughly to
struct my_struct *x;
struct my_struct arr[2];
// x is initialized somewhere
arr[0] = *x;
Instead it wants to call the generic function cffi:translate-into-foreign-memory. Is there any way SETF foreign memory to foreign memory, by passing this?

With the help of a few others on irc.freenode.net #lisp, we figured it out: use memcpy:
(cffi:with-foreign-objects ((x '(:struct my-struct))
(arr '(:struct my-struct) 2))
(cffi:foreign-funcall "memcpy"
:pointer (cffi:mem-aptr arr '(:struct my-struct) 0)
:pointer x
:int (cffi:foreign-type-size '(:struct my-struct))
:void))

Related

How to create and add items to dictionary

I am trying to create a dictionary or hash-table where keys are string and values are integers with following code:
(define dict #())
(dict-set! dict "bash" 1)
(displayln dict)
(dict-set! dict "racket" 1)
(displayln dict)
However, it gives following error:
dict-set!: contract violation
expected: (dict-implements/c dict-set!)
given: '#()
in: the d argument of
(->i
((d (dict-implements/c dict-set!))
(k (d) (dict-key-contract d))
(value (d) (dict-value-contract d)))
(_r void?))
contract from: <collects>/racket/dict.rkt
Where is the problem and how can it be solved?
The problem is that the literal #() is an empty vector.
To make a mutable hash table, use (make-hash).
(define dict (make-hash))

How does F# implement let rec?

I am wondering how F# implements let rec, and I couldn't find an answer. As a preface, I'll address how Scheme implements letrec:
In Scheme, let is just syntactics sugar for a definition of a lambda and applying it:
(let ((x 1)) (+ x 2))
is transformed to
((lambda (x) (+ x 2)) 1)
(in each case the expression is evaluated to 3).
letrec is also syntactic sugar, but #f is passed as initial argument to the lambda's parameters, and set! expressions are injected before the letrec body, like in this transformation:
(letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f).
Considering that F# doesn't have an equivalent operator to Scheme's set!, how does it implement let rec? Does it declare the function's parameters as mutable, and then mutate them in the function's body?
In F#, let rec allows a reference to the binding from within the function before it has been bound. let rec doesn't have an implementation per se, because it is merely a compiler hint.
In this contrived example,
let rec even =
function 0 -> true | 1 -> false | x -> odd (x - 1)
and odd =
function 0 -> false | 1 -> true | x -> even (x - 1)
the compiled IL very unglamorously translates to:
public static bool even(int _arg1)
{
switch (_arg1)
{
case 0:
return true;
case 1:
return false;
default:
return odd(_arg1 - 1);
}
}
public static bool odd(int _arg2)
{
switch (_arg2)
{
case 0:
return false;
case 1:
return true;
default:
return even(_arg2 - 1);
}
}
All function definitions are statically compiled to IL.
F# ultimately is a language which runs on the CLR.
There is no meta-programming.

Replace elements of a struct in Racket

Let's say that we have the following expression (band 'x (bor 'y 'z)), where band and bor boolean structs that have arg1 and arg2.
If I want to change the variables 'x and 'y to 'a and 'b by deep recursion on the expression, how can I do that?
There is a special form for functionally updating just some fields in a struct which is very nice to use where you have a lot of fields:
(struct person (name age occupation) #:transparent)
(define p (person "Per" 19 "Painter"))
(define (change-occupation p new-occupation)
(struct-copy person p [occupation new-occupation]))
(change-occupation p "Programmer") ; ==> (person "Per" 19 "Programmer")
Of course this is just a fancy way of writing:
(define (change-occupation p new-occupation)
(person (person-name p)
(person-age p)
new-occupation))
Now I don't know the names of your two structs but you may need to make a generic accessor unless one is subtype of the other:
(define (change-first obj new-value)
(if (band? obj)
(band new-value (band-second obj))
(bor new-value (bor-arg2 obj))))
Or you can just have similar case analysis in your procedure.

Why does `peek` with a polymorphic Ptr return GHC.Prim.Any when used with a bind?

Using the low-level GNU Science Library bindings Bindings.Gsl.RandomNumberGeneration, I'm running into this odd type behavior in GHCi where binding changes return type from a peek into GHC.Prim.Any. I'm trying to understand why since I can't use the c'rng_alloc unless I retain the type of pointer to an rng. For eample:
λ> :t c'gsl_rng_alloc
c'gsl_rng_alloc :: Ptr C'gsl_rng_type -> IO (Ptr C'gsl_rng)
λ> :t p'gsl_rng_mt19937
p'gsl_rng_mt19937 :: Ptr (Ptr gsl_rng_type)
λ> :t peek p'gsl_rng_mt19937
peek p'gsl_rng_mt19937 :: IO (Ptr gsl_rng_type)
λ> x <- peek p'gsl_rng_mt19937
λ> :t x
x :: Ptr GHC.Prim.Any
λ> c'gsl_rng_alloc x
<interactive>:421:17:
Couldn't match type ‘GHC.Prim.Any’ with ‘C'gsl_rng_type’
Expected type: Ptr C'gsl_rng_type
Actual type: Ptr GHC.Prim.Any
In the first argument of ‘c'gsl_rng_alloc’, namely ‘x’
In the expression: c'gsl_rng_alloc x
λ>
Trying to explicitly specify the type of the peek return that doesn't help either:
λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any
To expand somewhat on #user2407038's comment:
When you do x <- peek (ptr :: Ptr (Ptr a)) in the GHCi prompt, the type variable a must be instantiated to some concrete type. This is because the do notation x <- peek p means peek p >>= \x -> ..., where ... is what you type into GHCi afterwards. Since GHCi can't know the future, it has to "cheat" during typechecking.
Recall that in peek p >>= \x -> ..., the right-hand argument to >>=, namely the lambda abstraction \x -> ..., is monomorphic in its argument. This is why GHCi has to assign a monomorphic type to x.
GHC.Prim.Any is the placeholder type that GHC uses in situations like this where a concrete, monomorphic type needs to be assigned to something that has no other constraints.

SML syntactical restrictions within recursive bindings?

There seems to be syntactical restrictions within SML's recursive bindings, which I'm unable to understand. What are these restrictions I'm not encountering in the second case (see source below) and I'm encountering when using a custom operator in the first case?
Below is the case with which I encountered the issue. It fails when I want to use a custom operator, as explained in comments. Of the major SML implementations I'm testing SML sources with, only Poly/ML accepts it as valid, and all of MLton, ML Kit and HaMLet rejects it.
Error messages are rather confusing to me. The clearest one to my eyes, is the one from HaMLet, which complains about “illegal expression within recursive value binding”.
(* A datatype to pass recursion as result and to arguments. *)
datatype 'a process = Chain of ('a -> 'a process)
(* A controlling iterator, where the item handler is
* of type `'a -> 'a process`, so that while handling an item,
* it's also able to return the next handler to be used, making
* the handler less passive. *)
val rec iter =
fn process: int -> int process =>
fn first: int =>
fn last: int =>
let
val rec step =
fn (i: int, Chain process) (* -> unit *) =>
if i < first then ()
else if i = last then (process i; ())
else if i > last then ()
else
let val Chain process = process i
in step (i + 1, Chain process)
end
in step (first, Chain process)
end
(* An attempt to set‑up a syntax to make use of the `Chain` constructor,
* a bit more convenient and readable. *)
val chain: unit * ('a -> 'a process) -> 'a process =
fn (a, b) => (a; Chain b)
infixr 0 THEN
val op THEN = chain
(* A test of this syntax:
* - OK with Poly/ML, which displays “0-2|4-6|8-10|12-14|16-18|20”.
* - fails with MLton, which complains about a syntax error on line #44.
* - fails with ML Kit, which complains about a syntax error on line #51.
* - fails with HaMLet, which complains about a syntax error on line #45.
* The clearest (while not helpful to me) message comes from HaMLet, which
* says “illegal expression within recursive value binding”. *)
val rec process: int -> int process =
(fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process))))
val () = iter process 0 20
val () = print "\n"
(* Here is the same without the `THEN` operator. This one works with
* all of Poly/ML, MLton, ML Kit and HaMLet. *)
val rec process =
fn x =>
(print (Int.toString x);
Chain (fn x => (print "-";
Chain (fn x => (print (Int.toString x);
Chain (fn x => (print "|";
Chain process)))))))
val () = iter process 0 20
val () = print "\n"
(* SML implementations version notes:
* - MLton, is the last version, built just yesterday
* - Poly/ML is Poly/ML 5.5.2
* - ML Kit is MLKit 4.3.7
* - HaMLet is HaMLet 2.0.0 *)
Update
I could work around the issue, but still don't understand it. If I remove the outermost parentheses, then it validates:
val rec process: int -> int process =
fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process)))
Instead of:
val rec process: int -> int process =
(fn x => print (Int.toString x) THEN
(fn x => print "-" THEN
(fn x => print (Int.toString x) THEN
(fn x => print "|" THEN
process))))
But why is this so? An SML syntax subtlety? What's its rational?
It's just an over-restrictive sentence in the language definition, which says:
For each value binding "pat = exp" within rec, exp must be of the form "fn match".
Strictly speaking, that doesn't allow any parentheses. In practice, that's rarely a problem, because you almost always use the fun declaration syntax anyway.

Resources