how to retrieve errno from an os error? - clisp

This question is divided into two parts.
Part one:
I run this ...
1 (handler-case (posix:kill 1 0)
2 (error (the-condition) (prin1 (type-of the-condition)) (terpri)
3 (princ the-condition) (terpri)))
... and get this output:
SYSTEM::SIMPLE-OS-ERROR
UNIX error 1 (EPERM): Operation not permitted
I can use #'princ-to-string and parse the string to get the error number. But is there a more direct way to retrieve errno? Something like #'file-error-pathname, but for errno instead?
Part two:
Where in the documentation could I have found the answer to Part one?

Released version
The released version 2.49 does not have an accessor for the errno.
You can get it, however, thusly:
[4]> (setq c (nth-value 1 (ignore-errors (posix:kill 1 0))))
#<SYSTEM::SIMPLE-OS-ERROR #x00000002002634A1>
[5]> (describe c)
#<SYSTEM::SIMPLE-OS-ERROR #x000000020021AF69> is an instance of the CLOS class #1=#<STANDARD-CLASS SYSTEM::SIMPLE-OS-ERROR>.
Slots:
SYSTEM::$FORMAT-CONTROL =
"UNIX error ~S (EPERM): Operation not permitted
"
SYSTEM::$FORMAT-ARGUMENTS = (1)
"UNIX error ~S (EPERM): Operation not permitted
" is a simple 1 dimensional array (vector) of CHARACTERs, of size 47 (a ISO-8859-1 string).
(1) is a list of length 1.
[6]> (car (slot-value c 'SYSTEM::$FORMAT-ARGUMENTS))
1
Development version
The dev version in the tip of the mercurial repo has os-error instead:
[1]> (setq c (nth-value 1 (ignore-errors (posix:kill 1 0))))
#<OS-ERROR #x0000000200253301>
[2]> (describe c)
#<OS-ERROR #x0000000200253301> is an instance of the CLOS class #1=#<STANDARD-CLASS OS-ERROR>.
Slots:
SYSTEM::$CODE = 1
1 is an integer, uses 1 bit, is represented as a fixnum.
[6]> (apropos "os-error")
OS-ERROR class
OS-ERROR-CODE function
EXT::OS-ERROR-CODE-1
[10]> (os-error-code c)
1

Related

How can I convert this list of numbers and symbols into a string?

is there a way too convert a list like this into a normal string?
list->string does not work because it isn't a list of chars.
It is a bit problematic because the list consists of symbols and numbers :/
(list + 4 * 5 - 3 6) //-> "+4*5-36"
Standard Scheme
For numbers:
(number->string 123 10) ; ==> "123"
For symbols:
(symbol->string 'test) ; ==> "test"
So you can check what type it is and use the correct procedure to convert to string. You can use string-append so join more strings together.
(string-append (symbol->string '+)
(number->string 4)
(symbol->string '*)
(number->string 5)
(symbol->string '-)
(number->string 3)
(number->string 6))
; ==> "+4*5-36"
If you make a procedure any->string you can make a one level list to string like this with SRFI-1:
(foldr (lambda (e a) (string-append (any->string e) a))
""
'(+ 4 * 5 - 3 6))
; ==> "+4*5-36"
Racket
Racket has format. If you do (format "~a" data) it will produce a string:
(format "~a" '(+ 4 * 5 - 3 6))
; ==> "(+ 4 * 5 - 3 6)"
Note that the first element of (list + 4 * 5 - 3 6) isn't the symbol + since the variable + gets evaluated to a procedure that adds stuff. eg. (+ 3 4) ; ==> 7 and + ; ==> #<procedure:+> (in racket; implementation specific)
I will show you in mit-scheme:
(define input '(+ 4 * 5 - 3 6))
(fold-right (lambda (x acc)
(string-append ((cond ((number? x) number->string )
((symbol? x) symbol->string ))
(else (error "unknown case" x))
x)
acc))
""
input)
Example:
1 ]=>
(define input '(+ 4 * 5 - 3 6))
;Value: input
...
;Value: "+4*5-36"
In case the list contains more kind of symbolic expressions, apart from numbers and symbols, you extend the cond-statement with other cases.
Also, do not forget to quote the input, otherwise + gets evaluated to a strange value.

How to fix indentation problem with haskell if statement

I have the following Haskell code:
f :: Int -> Int
f x =
let var1 = there in
case (there) of
12 -> 0
otherwise | (there - 1) >= 4 -> 2
| (there + 1) <= 2 -> 3
where there = 6
The function alone is garbage, ignore what exactly it does.
I want to replace the guards with if
f x =
let var1 = there in
case (there) of
12 -> 0
otherwise -> if (there - 1) >= 4 then 2
else if (there + 1) <= 2 then 3
where there = 6
I tried moving the if to the next line, the then to the next line, lining them up, unlining them, but nothing seems to work.
I get a parsing error and I don't know how to fix it:
parse error (possibly incorrect indentation or mismatched brackets)
|
40 | where there = 6
| ^
You have a few misunderstandings in here. Let's step through them starting from your original code:
f x =
A function definition, but the function never uses the parameter x. Strictly speaking this is a warning and not an error, but most code bases will use -Werror so consider omitting the parameter or using _ to indicate you are explicitly ignoring the variable.
let var1 = there in
This is unnecessary - again you are not using var1 (the below used there) so why have it?
case (there) of
Sure. Or just case there of, not need for excessive parens cluttering up the code.
12 -> 0
Here 12 is a pattern match, and it's fine.
otherwise ->
Here you used the variable name otherwise as a pattern which will uncondtionally match the value there. This is another warning: otherwise is a global value equal to True so it can be used in guards, such as function foo | foo < 1 = expr1 ; | otherwise = expr2. Your use is not like that, using otherwise as a pattern shadows the global value. Instead consider the catch all pattern with underscore:
_ -> if (there - 1) >= 4
then 2
else if (there + 1) <= 2
then 3
where there = 6
Ok... what if there was equal to 3? 3-1 is not greater than 4. 3+1 is not less than 2. You always need an else with your if statement. There is no if {} in Haskell instead there is if ... else ... much like the ternary operator in C, as explained in the Haskell wiki.

Fortran nested WHERE statement

I have a Fortran 90 source code with a nested WHERE statement. There is a problem but it seems difficult to understand what exactly happens. I would like to transform it into DO-IF structure in order to debug. What it is not clear to me is how to translate the nested WHERE.
All the arrays have the same size.
WHERE (arrayA(:) > 0)
diff_frac(:) = 1.5 * arrayA(:)
WHERE (diff_frac(:) > 2)
arrayC(:) = arrayC(:) + diff_frac(:)
ENDWHERE
ENDWHERE
My option A:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
DO j=1, SIZE(diff_frac)
IF (diff_frac(j) > 2) THEN
arrayC(j) = arrayC(j) + diff_frac(j)
ENDIF
ENDDO
ENDIF
ENDDO
My option B:
DO i=1, SIZE(arrayA)
IF (arrayA(i) > 0) THEN
diff_frac(i) = 1.5 * arrayA(i)
IF (diff_frac(i) > 2) THEN
arrayC(i) = arrayC(i) + diff_frac(i)
ENDIF
ENDIF
ENDDO
Thank you
According to the thread "Nested WHERE constructs" in comp.lang.fortran (particularly Ian's reply), it seems that the first code in the Question translates to the following:
do i = 1, size( arrayA )
if ( arrayA( i ) > 0 ) then
diff_frac( i ) = 1.5 * arrayA( i )
endif
enddo
do i = 1, size( arrayA )
if ( arrayA( i ) > 0 ) then
if ( diff_frac( i ) > 2 ) then
arrayC( i ) = arrayC( i ) + diff_frac( i )
endif
endif
enddo
This is almost the same as that in Mark's answer except for the second mask part (see below). Key excerpts from the F2008 documents are something like this:
7.2.3 Masked array assignment – WHERE (page 161)
7.2.3.2 Interpretation of masked array assignments (page 162)
... 2. Each statement in a WHERE construct is executed in sequence.
... 4. The mask-expr is evaluated at most once.
... 8. Upon execution of a WHERE statement that is part of a where-body-construct, the control mask is established to have the value m_c .AND. mask-expr.
... 10. If an elemental operation or function reference occurs in the expr or variable of a where-assignment-stmt or in a mask-expr, and is not within the argument list of a nonelemental function reference, the operation is performed or the function is evaluated only for the elements corresponding to true values of the control mask.
If I understand the above thread/documents correctly, the conditional diff_frac( i ) > 2 is evaluated after arrayA( i ) > 0, so corresponding to double IF blocks (if I assume that A .and. B in Fortran does not specify the order of evaluation).
However, as noted in the above thread, the actual behavior may depend on compilers... For example, if we compile the following code with gfortran5.2, ifort14.0, or Oracle fortran 12.4 (with no options)
integer, dimension(4) :: x, y, z
integer :: i
x = [1,2,3,4]
y = 0 ; z = 0
where ( 2 <= x )
y = x
where ( 3.0 / y < 1.001 ) !! possible division by zero
z = -10
end where
end where
print *, "x = ", x
print *, "y = ", y
print *, "z = ", z
they all give the expected result:
x = 1 2 3 4
y = 0 2 3 4
z = 0 0 -10 -10
But if we compile with debugging options
gfortran -ffpe-trap=zero
ifort -fpe0
f95 -ftrap=division (or with -fnonstd)
gfortran and ifort abort with floating-point exception by evaluating y(i) = 0 in the mask expression, while f95 runs with no complaints. (According to the linked thread, Cray behaves similarly to gfortran/ifort, while NAG/PGI/XLF are similar to f95.)
As a side note, when we use "nonelemental" functions in WHERE constructs, the control mask does not apply and all the elements are used in the function evaluation (according to Sec. 7.2.3.2, sentence 9 of the draft above). For example, the following code
integer, dimension(4) :: a, b, c
a = [ 1, 2, 3, 4 ]
b = -1 ; c = -1
where ( 3 <= a )
b = a * 100
c = sum( b )
endwhere
gives
a = 1 2 3 4
b = -1 -1 300 400
c = -1 -1 698 698
which means that sum( b ) = 698 is obtained from all the elements of b, with the two statements evaluated in sequence.
Why not
WHERE (arrayA(:) > 0)
diff_frac(:) = 1.5 * arrayA(:)
ENDWHERE
WHERE (diff_frac(:) > 2 .and. arrayA(:) > 0)
arrayC(:) = arrayC(:) + diff_frac(:)
ENDWHERE
?
I won't say it can't be done with nested wheres, but I don't see why it has to be. Then, if you must translate to do loops, the translation is very straightforward.
Your own attempts suggest you think of where as a kind of looping construct, I think it's better to think of it as a masked assignment (which is how it's explained in the language standard) in which each individual assignment happens at the same time. These days you might consider translating into do concurrent constructs.
Sorry about deflecting the question a bit, but this is interesting. I am not sure that I can tell how the nested where is going to be compiled. It may even be one of those cases that push the envelope.
I agree with High Performance Mark that where is best thought of as a masking operation and then it is unclear (to me) whether your "A" or "B" will result.
I do think that his solution should be the same as your nested where.
My point: Since this is tricky to even discern, can you write new code instead of this, from scratch? Not to translate it, but delete it, forget about it, and write code to do the job.
If you know exactly what this piece of code needs to do, its pre- and post- conditions, then it shouldn't be difficult. If you don't know that then the algorithm may be too entangled in which case this should be rewritten anyway. There may be subtleties involved between what this was intended to do and what it does. You say you are debugging this code already.
Again, sorry to switch context but I think that there is a possibility that this is one of those situations where code is best served by a complete rewrite.
If you want to keep it and only write loops for debugging: Why not write them and compare output?
Run it with where as it is, then run it with "A" instead, then with "B". Print values.

`.split` method in clojure returns unexpected results

For part of a class project I need to read in a file representing a graph in Clojure. Here is a link to an example file. The file structure for all the files I could possibly read in are such
c Unknown number of lines
c That start with "c" and are just comments
c The rest of the lines are edges
e 2 1
e 3 1
e 4 1
e 4 2
e 4 3
e 5 1
e 5 2
The issue that I am having is trying to split a line based on spaces. In my REPL I have done
finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;#180f214>
Which, I am not sure what it means exactly.. I think it refers to a memory locations of a String[] I am not sure why it is displayed like that though. If the insert a # in front of the split string, which I think denotes it is a regular expression I receive an error
finalproject.core> (.split "e 1 2" #" ")
ClassCastException java.util.regex.Pattern cannot be cast to java.lang.String
Currently my entire implementation of this module is, which I am pretty sure will work if I could properly use the split function.
(defn lineToEdge [line]
(cond (.startsWith line "e")
(let [split-line (.split line " ")
first-str (split-line 1)
second-str (split-line 2)]
((read-string first-str) (read-string second-str)))))
(defn readGraphFile [filename, numnodes]
(use 'clojure.java.io)
(let [edge-list
(with-open [rdr (reader filename)]
(doseq [line (line-seq rdr)]
(lineToEdge line)))]
(reduce add-edge (empty-graph numnodes) edge-list)))
I have not had a chance to test readGraphFile in any way but when I try to use lineToEdge with some dummy input I receive the error
finalproject.core> (lineToEdge "e 1 2")
ClassCastException [Ljava.lang.String; cannot be cast to clojure.lang.IFn
Suggestions as to where I went wrong?
In the following, your return value is an Array of type String.
finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;#180f214>
To use it more conveniently in Clojure, you can put it into a vector:
user=> (vec (.split "e 1 2" " "))
["e" "1" "2"]
You can also use the built in clojure.string namespace:
user=> (require '[clojure.string :as string])
nil
user=> (string/split "e 1 2" #" ")
["e" "1" "2"]
The source of your stack trace is here:
(let [split-line (.split line " ")
first-str (split-line 1)
second-str (split-line 2)] ...)
This gets a String Array, via .split, then attempts to call it as if it were a function. Perhaps you meant to use get here to access an element of the List by index? (get split-line 1) will get the element from split-line at index 1, etc.
You'll see another problem here:
((read-string first-str) (read-string second-str))
If I am reading your code properly, this will end up calling a number as if it were a function, with another number as an argument. Perhaps you intend to return a pair of numbers?
[(read-string first-str) (read-string second-str)]

How to initialize a string with a fill pointer in Common Lisp?

I want to use formatted output in a loop to generate a string. Manual says it can be easily done by giving format function a string with a fill pointer as a destination. Unfortunately, it is not transparent from the manual how to initialize this string in the first place.
I tried (string "") and (format nil "") with no luck.
(make-array 0 :element-type 'character :fill-pointer 0) did work for me, but it just doesn't feel right.
What is the proper way to initialize a string with a fill pointer?
(make-array estimated-size-of-final-string
:element-type 'character :fill-pointer 0)
(with :adjustable t too if the estimate is inaccurate) is one way; for accumulating output to produce a string it may be more idiomatic to use with-output-to-string:
(with-output-to-string (stream)
(loop repeat 8 do (format stream "~v,,,'-#A~%" (random 80) #\x)))
=>
"----------------------------------x
--------x
--------------------------------------x
----------------------------------------------------------------x
--------------x
-----------------------------------------x
---------------------------------------------------x
-----------------------------------------------------------x
"
(make-array 0 :element-type 'character :fill-pointer 0) is the canonical way (well, it's quite possible to use an initial non-zero length and use :initial-contents with a string value). It's also possible to specify the fil-pointer value as t, that will set the fill-pointer at the end of the string.
Using FORMAT to a string with a fill pointer is a very rarely used functionality.
CL-USER 125 > (let ((s (make-array 0
:element-type 'character
:adjustable t
:fill-pointer t)))
(format s "Hello, ~a!" 'bill)
s)
"Hello, BILL!"
CL-USER 126 > (describe *)
"Hello, BILL!" is an (ARRAY CHARACTER (12))
FILL-POINTER 12
0 #\H
1 #\e
2 #\l
3 #\l
4 #\o
5 #\,
6 #\Space
7 #\B
8 #\I
9 #\L
10 #\L
11 #\!

Resources