I was trying to write my own put-pixel on (Gdk) pixbuf in Lisp. When I finally realized how I can operate on C pointers in CL, new obstacle came along - (gdk:pixbuf-get-pixels pb) returns me negative number. My question is: can I convert it somehow to a valid pointer? My attempts to use cffi:convert-from-foreign and cffi:translate-from-foreign (what's the difference between them anyway?) failed.
Below is my actual (not working) code:
(defun put-pixel (pixbuf x y r g b)
(let ((p (+ (gdk:pixbuf-get-pixels pixbuf) (* x (gdk:pixbuf-get-n-channels pixbuf)) (* y (gdk:pixbuf-get-rowstride pixbuf)))))
(setf (cffi:mem-aref p :unsigned-char 0) r)
(setf (cffi:mem-aref p :unsigned-char 1) g)
(setf (cffi:mem-aref p :unsigned-char 2) b)))
CFFI:TRANSLATE-FROM-FOREIGN is a generic function. You can define your own foreign types using CFFI:DEFINE-FOREIGN-TYPE and then add a method to CFFI:TRANSLATE-FROM-FOREIGN to specify how the conversions from foreign to Lisp values should work.
CFFI:CONVERT-FROM-FOREIGN is what you should call if you need to explicitly convert some value. It will call CFFI:TRANSLATE-FROM-FOREIGN behind the scenes and it might perform some compile-time optimizations if possible.
Same thing applies to CFFI:CONVERT-TO-FOREIGN and CFFI:TRANSLATE-TO-FOREIGN.
I think that lambda-gtk incorrectly defined binding for pixbuf-get-pixels.
The negative value for pointer value might appear because of incorrect interpretation of unsigned integer as a signed integer.
The simplest way to correct this value is to use mod:
CL-USER> (mod -1 (expt 2 #+cffi-features:x86 32 #+cffi-features:x86-64 64))
4294967295
Related
Is there a way to get a unique identifier for an object in Racket? For instance, when we use Racket's eq? operator to check whether two variables refer to the same object, what identifier is it using to achieve this comparison?
I'm looking for something like python's id function or Ruby's object_id method, in other words, some function id such that (= (id obj) (id obj2)) means that (eq? obj obj2) is true.
Some relevant docs:
Object Identity and Comparisons
Variables and Locations
Is eq-hash-code what you want?
> (define l1 '(1))
> (define l2 '(1))
> (eq? l1 l2)
#f
> (eq-hash-code l1)
9408
> (eq-hash-code l2)
9412
There's a way to get a C pointer of an object via ffi/unsafe, with the obvious caveat that it's UNSAFE.
;; from https://rosettacode.org/wiki/Address_of_a_variable#Racket
(require ffi/unsafe)
(define (madness v) ; i'm so sorry
(cast v _racket _gcpointer))
To use it:
(define a (list 1 2))
(define b (list 1 2))
(printf "a and b have different address: ~a ~a\n"
(equal? (madness a) (madness b))
(eq? a b))
(printf "a and a have the same address: ~a ~a\n"
(equal? (madness a) (madness a))
(eq? a a))
(printf "1 and 1 have the same address: ~a ~a\n"
(equal? (madness 1) (madness 1))
(eq? 1 1))
Though the pointer is not a number or an identifier. It's an opaque object... So in a sense, this is kinda useless. You could have used the real objects with eq? instead.
I also don't know any guarantee of this method. In particular, I don't know if the pointer will be updated to its latest value when the copy GC copies objects.
Here is an implementation of such a function using a weak hash table.
Using a weak hash table ensures that objects are garbage collected correctly
even if we have given it an id.
#lang racket
(define ht (make-weak-hasheq))
(define next 0)
(define (get-id x)
(define id (hash-ref ht x #f))
(or id
(begin0
next
(hash-set! ht x next)
(set! next (+ next 1)))))
(get-id 'a)
(get-id 'b)
(get-id 'a)
Note that Sylwester's advice is sound. The standard is to store the value directly.
You most likely won't find an identity, but the object itself is only eq? with itself and nothing else. eq? basically compares the address location of the values. So if you want an id you can just store the whole object at that place and it will be unique.
A location is a binding. Think of it as an address you cannot get and an address which has an address to a object. Eg. a binding ((lambda (a) a) 10) would store the address location of the object 10 in the first stack address and the code in the body just returns that same address. A location can change by set! but you'll never get the memory location of it.
It's common for lisp systems to store values in pointers. That means that some types and values doesn't really have an object at the address, but the address has a value and type encoded in it that the system knows. Typically small integers, chars, symbols and booleans can be pointer equal even though they are constructed at different times. eg. '(1 2 3) would only use 3 pairs and not any space for the values 1-3 and ().
For the expression
(define x (length (range 3000)))
I think it is evaluated to
(define x 3000)
For the expression
(define (f x) (length (range 3000)))
Does it evaluate to the following as well?
(define (f x) 3000)
No, they evaluate to two different procedures, with different bodies. A completely different matter is that when executed, they both will return the same value, namely 3000, ignoring the parameter in both cases. To be clear, the first expression binds f to a lambda (this is how define expands a procedure definition under the hood):
(define f
(lambda (x) (length (range 3000))))
The second expression also binds f to a lambda, but it's a different one:
(define f
(lambda (x) 3000))
Either one will return 3000 when invoked:
(f 42)
=> 3000
But the first one will do more work, it has to create a range and calculate its length, whereas the second one simply returns 3000. Regarding your first example - in the end x will have the same value, and it won't matter how you calculated it. But for the second example, the two fs are different objects, even though the values they calculate are the same.
I am totally new to lisp and have no idea how I'll create this function.
This is the pseudo code I created to help me solve it
Binary tree children
; This function returns the children of binary tree node
; e.g., 3 -> (6,7)
; e.g., 11 -> (22,23)
(defun tree-node(x))
The function is intended to take in a number, double it, and then double it and add 1. Please help.
To double a number (which is stored in a variable named n here): (* 2 n).
To add one: (1+ n). Note that 1+ is the name of a function. It is the same as (+ n 1).
Now, let's say that you have some scope (e. g. a function body) where you have a variable named n. You now create a new variable d using let:
(let ((d (* n 2)))
…)
This new variable is in scope for the body of the let (indicated by … above).
Now we create another variable d1, which is one more. We need to use let* now, so that the scope of d is not just the body, but also the binding forms of the let*:
(let* ((d (* n 2))
(d1 (+ d 1)))
…)
The function should maybe be called child-indices:
(defun child-indices (n)
(let* ((d (* n 2))
(d1 (+ d 1)))
…))
The bodies of many forms like defun and let are so-called implicit progns, which means that these forms return the value of the last expression in their body. So, whatever forms we put into the place marked … above, the value (or values, but let's keep that aside for now) of the last is the return value of the function.
There are several ways to do a “return this and then that”, but we'll use a list for now:
(defun child-indices (n)
(let* ((d (* n 2))
(d1 (+ d 1)))
(list d d1)))
Define a function "power" that takes two input arguments m and n, and returns m^n. Then, by using the function "power", define a function sum_power that takes two input arguments m and n and returns the sum: (1^n + 2^n + 3^n +.... + m^n).
int first function i calculate power from given arguments in second function a sum powers. But program gives error: Program stack overflow. RESET...
I cant find my error. Function power is correct I checked.
(defun power(m n)
(let ((result 1))
(dotimes (count n result)
(setf result (* m result)))))
(defun sum_power (m n)
(if (= 0 m)
0
(+ (powern m)
(sum_power (1- m) n))))
Ok the problem is your function sum_power when you pass the variable m
the expression (- 1 m) is an infinite loop first time because is for example
for m = 5 first time (- 1 m) => -4 (new m = -4) second time (- 1 m)
=> 5 (new m = 5)
begin again so is a recusive infinite loop, you never arrive to 1 so this is teh case of the overflow
Use instead the build function (1- m) which decreases the value of m, or (- m 1) if you want
So the new funtion will be like this, also this is no tail recursion so for big m and n it will take a lot of time, but for your needs it should work, and this function is better formated, please take of fromatting when writing lisp functions for easy reading
(defun sum_power (m n)
(if (= 1 m)
1
(+ (power n m) (sum_power (1- m) n))
You have a argument order mistake in your sum_power function. The stand lisp function - when given two arguments subtracts the second argument from the first argument that is (- 1 m) will subtract m from one and NOT 1 from m as you probably expected thus your result will be a negative integer and your base case (= 1 m) will never be reached. For you code to work correctly you have to swap the arguments to - thus (- m 1) or you can user the lisp function 1- (1- m) which subtracts one from its only argument thus a corrected version of your code is as follows:
(defun sum_power (m n)
(if (= 1 m)
1
(+ (power m n) (sum_power (1- m) n))))
On a non-related side-note lisp allows a lot more characters in function, variable and macro names than most other languages thus you can use sum-power instead of sum_power, in-fact it is arguably better lisp style to use hyphens to join multiple-word identifier names rather than underscores (as used in C) or camel-back casing (sumPower as used in Java). Secondly closing parenthesis usually are not written on a separate line but are on the same line as the last expression before the closing parentheses, as I have done above in the corrected version. These are merely conventions you may follow them if you wish but you're not obliged to.
Why you don't use higher-order functions and loop macro? I think is more readable that way:
(defun power (n m)
(reduce #'* (loop for x below n collect m))
(defun sum-power (n m)
(reduce #'+ (loop for x from 1 to m collect (power x n)))
I decided to learn LISP today, and have been playing around with it for a bit. I wrote a simple baby function just to test my understanding, and now understand that my understanding doesn't understand as much as I had understood it to understand. :D
Anyway, here is the function. The idea is that when it is called, e.g. (esexp base x) it should return the value base^x. So (esexp 3 4) = 3^4 = 81.
(I am using the CMU implementation of Common Lisp, if that matters.)
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ esexp (base (+ x 1)) base)
(* esexp (base (+ x 1)) base))))
This doesn't work. I get errors that look like (Warning: This variable is undefined: SLBEXP) and (Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable SLBEXP is unbound.) So. What am I doing wrong? AND would there be a better (or more LISP-ish way) to write this function?
ETA
Corrected code:
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ (esexp base (+ x 1)) base)
(* (esexp base (- x 1)) base))))
esexp(base (+ x 1))
should be
(esexp base (+ x 1))
esexp is a function just like +. The syntax for invoking a function is
(function-name arg1 arg2 ...)
The technical explanation of the error: the compiler was parsing the code:
(/ esexp(base (+ x 1)) base)
as this:
(/ esexp (base (+ x 1)) base)
which says:
first, add 1 to the parameter x
then, invoke a function called base with the result above.
divide the value of a variable called esexp by the result above.
then, divide that result by the parameter base. (The divide operator in Common Lisp can take more than two arguments.)
You see the trick? When a word appears as the first item in a s-expression (and that s-expression isn't quoted), it's usually treated as the name of a function you want to invoke. Otherwise, it's treated as the name of a variable whose value you want to retrieve. Further, in Common Lisp a symbol like esexp can be bound to both a function value and a variable value at the same time; context or special expressions like #'esexp (which means the function) are used to figure out which one you mean.
The compiler was telling you that, though esexp was bound to a function with your defun statement, it had not yet been bound to a variable value, and therefore could not be used as such. Hence, the error.
Just a note about the code. I believe it should be
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ (esexp(base (+ x 1)) base))
(* (esexp(base (- x 1)) base))))
Otherwise the function will never terminate. (you had (* (esexp(base (+ x 1)) base)))))