Importing strings to Scheme without using open-input-string - string

I am trying to have my Scheme program import strings without needing to use open-input-string before the string. So for example, right now I can do the following:
> (scheme_lexer (open-input-string "3+4*2"))
However, is there a way for my program to work if I input the string this way?:
> (scheme_lexer ("3+4*2"))
Thank you!

Is there any particular reason you can't just make a scheme_lexer_string function that does this for you when dealing with strings? The extra parentheses just seem like clutter, and they make a macro the only real solution. If you dropped that requirement and made something like (scheme_lexer "3+4*2") acceptable, you can make an ordinary function for handling strings:
(define (scheme_lexer_string s)
(scheme_lexer (open-input-string s)))
If what you want is a function that handles both input ports and strings, you can make a general function that dispatches based on the type of the argument to the specific functions. In this case, your original scheme_lexer would be renamed to scheme_lexer_input_port and you would have these functions:
(define (scheme_lexer_string s)
(scheme_lexer_input_port (open-input-string s)))
(define (scheme_lexer in)
(if (string? in)
(scheme_lexer_string in)
(scheme_lexer_input_port in)))
Now scheme_lexer works for both strings and ports and dispatches to the correct function as desired.
> (scheme_lexer some-input-port)
... evaluates the content in the port
> (scheme_lexer "abcd")
... evaluates the string "abcd"

Here is one option. I have used a testing function lexer just to show the macro. You can adjust it to your needs.
(define (lexer sp) (read sp))
(define-syntax scheme_lexer
(syntax-rules ()
((_ (input))
(lexer (open-input-string input)))))
And to test:
> (scheme_lexer ("3+4*2"))
'3+4*2

Related

Recursively reading a file in Racket

I am struggling to understand how to read a file line by line with racket, while passing each line to a recursive function.
According to the manual, the idiomatic way of doing this is something like the following example:
(with-input-from-file "manylines.txt"
(lambda ()
(for ([l (in-lines)])
(op l))))
What if my function op is a recursive function that needs to do some complicated operations depending on the line just read from file and also on the history of the recursion?
For example, I could have a function like this:
(define (op l s)
;; l is a string, s is a list
(cond ((predicate? l)
(op (next-line-from-file) (cons (function-yes l) s)))
(else
(op (next-line-from-file) (append (function-no l) s)))))
I am not sure how to use this function within the framework described by the manual.
Here next-line-from-file is a construct I made up to make it clear that I would like to keep reading the file.
I think I could do what I want by introducing side effects, for example:
(with-input-from-file "manylines.txt"
(lambda ()
(let ((s '()))
(for ([l (in-lines)])
(if (predicate? l)
(let ((prefix (function-yes l)))
(set-cdr! s s)
(set-car! s prefix))
(let ((prefix (function-no l)))
(set-cdr! prefix s)
(set-car! s prefix)))))))
I actually did not try to run this code, so I'm not sure it would work.
Anyway I would bet that this common task can be solved without introducing side effects, but how?
Two approaches that Racket supports rather well are to turn the port into something which is essentially a generator of lines, or into a stream. You can then pass these things around as arguments to whatever function you are using in order to successively read lines from the file.
The underlying thing in both of these is that ports are sequences, (in-lines p) returns another sequence which consists of the lines from p, and then you can turn these into generators or streams.
Here's a function which will cat a file (just read its lines in other words) using a generator:
(define (cat/generator f)
(call-with-input-file f
(λ (p)
(let-values ([(more? next) (sequence-generate (in-lines p))])
(let loop ([carry-on? (more?)])
(when carry-on?
(displayln (next))
(loop (more?))))))))
Here call-with-input-file deals with opening the file and calling its second argument with a suitable port. in-lines makes a sequence of lines from the port, and sequence-generate then takes any sequence and returns two thunks: one tells you if the sequence is exhausted, and one returns the next thing in it if it isn't. The remainder of the function just uses these functions to print the lines of the file.
Here's an equivalent function which does it using a stream:
(define (cat/stream f)
(call-with-input-file f
(λ (p)
(let loop ([s (sequence->stream (in-lines p))])
(unless (stream-empty? s)
(displayln (stream-first s))
(loop (stream-rest s)))))))
Here the trick is that sequence->stream returns a stream corresponding to a sequence, and then stream-empty? will tell you if you're at the end of the stream, and if it's not empty, then stream-first returns the first element (conceptually the car) while stream-rest returns a stream of all the other elements.
The second one of these is nicer I think.
One nice thing is that lists are streams so you can write functions which use the stream-* functions, test them on lists, and then use them on any other kind of stream, which means any other kind of sequence, and the functions will never know.
I recently implement something similar, except in my case the predicate depended on the following line, not the preceding one. In any case, I found it simplest to discard in-lines and use read-line recursively. Since the predicate depended on unread input, I used peek-string to look ahead in the input stream.
If you really want to use in-lines, you might like to experiment with sequence-fold:
(sequence-fold your-procedure '() (in-lines))
Notice this uses an accumulator, which you could use to check the previous results from your procedure. However, if you're building a list, you generally want to build it backwards using cons, so the most recent element is at the head of the list and can be accessed in constant time. Once you're done, reverse the list.

Switch statement in Lisp

Switch statement with Strings in Lisp.
(defun switch(value)
(case value
(("XY") (print "XY"))
(("AB") (print "AB"))
)
)
I want to compare if value is "XY" then print "XY" or same for "AB".
I have tried this code but it gives me nil. Can some please tell me what i am doing wrong?
You can use the library alexandria, which has a configurable switch macro:
(switch ("XY" :test 'equal)
("XY" "an X and a Y")
("AB" "an A and a B"))
print("XY") looks more like Algol (and all of its descendants) rather than LISP. To apply print one would surround the operator and arguments in parentheses like (print "XY")
case happens to be a macro and you can test the result yourself with passing the quoted code to macroexpand and in my implementation I get:
(let ((value value))
(cond ((eql value '"XY") (print "XY"))
((eql value '"AB") (print "AB"))))
You should know that eql is only good for primiitive data types and numbers. Strings are sequences and thus (eql "XY" "XY") ;==> nil
Perhaps you should use something else than case. eg. use cond or if with equal.
The Hyperspec on CASE says:
These macros allow the conditional execution of a body of forms in a clause that is selected by matching the test-key on the basis of its identity.
And strings are not identical in CL, i.e. (EQ "AB" "AB") => NIL.
That is why CASE wouldn't work for strings. You either need to use symbols (they are interned once only, thus guaranteeing identity) or use COND with EQUAL or even EQUALP if the letters case to be ignored.

Is there a single function that concat a string to every entry in a list?

(setq a '("bar" "baz" "barz"))
(setq prefix "foo")
;; Expected result
==> ("foobar" "foobaz" "foobarz")
I have been doing this by dolist or iterating through car. Is there a single function doing the same job?
Not a single function, but I would use:
(mapcar (apply-partially #'concat prefix) a)
There are lots of ways you could do this, though, and there's probably nothing particularly wrong with what you were doing.

How do you call functions dynamically with Haskell

I'm looking to call functions dynamically based on the contents found in an association list.
Here is an example in semi-pseudo-code. listOfFunctions would be passed to callFunctions.
listOfFunctions = [('function one', 'value one')
, ('function two', 'value two')
, ('function three', 'value three')]
callFunctions x = loop through functions
if entry found
then call function with value
else do nothing
The crux of the question is not looping through the list, rather, it's how to call a function once I have it's name?
Consider this use case for further clarification. You open the command prompt and are presented with the following menu.
1: Write new vHost file
2: Exit
You write the new vHost file and are not presented with a new menu
1: Enter new directive
2: Write file
3: Exit
You enter some new directives for the vHost and are now ready to write the file.
The program isn't going to blindly write each and every directive it can, rather, it will only write the ones that you supplied. This is where the association list comes in. Writing a giant if/then/else or case statement is madness. It would be much more elegant to loop through the list, look for which directives were added and call the functions to write them accordingly.
Hence, loop, find a function name, call said function with supplied value.
Thanks to anyone who can help out with this.
Edit:
Here is the solution that I've come up with (constructive critiques are always welcome).
I exported the functions which write the directives in an association list as every answer provided said that just including the function is the way to go.
funcMap = [("writeServerName", writeServerName)
,("writeServeralias", writeServerAlias)
,("writeDocRoot", writeDocRoot)
,("writeLogLevel", writeErrorLog)
,("writeErrorPipe", writeErrorPipe)
,("writeVhostOpen", writeVhostOpen)]
In the file which actually writes the hosts, that file is imported.
I have an association list called hostInfo to simulate some dummy value that would be gathered from an end-user and a function called runFunction which uses the technique supplied by edalorzo to filter through both the lists. By matching on the keys of both lists I ensure that the right function is called with the right value.
import Vhost.Directive
hostInfo = [("writeVhostOpen", "localhost:80")
,("writeServerName", "norics.com")]
runFunctions = [f val | (mapKey, f) <- funcMap, (key, val) <- hostInfo, mapKey == key]
You can simply include the function in the list directly; functions are values, so you can reference them by name in a list. Once you've got them out of the list, applying them is just as simple as func value. There's no need to involve their names at all.
Since I am farily new to Haskell I will risk that you consider my suggestion very naive, but anyways here it goes:
let funcs = [("sum", (+3),1),("product", (*3),2),("square", (^2),4)]
[f x | (name, f, x) <- funcs, name == "sum"]
I think it satisfies the requirements of the question, but perhaps what you intend is more sofisticated than what I can see with my yet limitted knowledge of Haskell.
It might be a bit of an overkill (I agree with ehird's reasoning) but you can evaluate a string with Haskell code by using the eval function in System.Eval.Haskell.
EDIT
As pointed out in the comments, hint is a better option for evaluating strings with Haskell expressions. Quoting the page:
This library defines an Interpreter monad. It allows to load Haskell modules, browse them, type-check and evaluate strings with Haskell expressions and even coerce them into values. The library is thread-safe and type-safe (even the coercion of expressions to values). It is, esentially, a huge subset of the GHC API wrapped in a simpler API. Works with GHC 6.10.x and 6.8.x
First we define our list of functions. This could be built using more machinery, but for the sake of example I just make one explicit list:
listOfFunctions :: [(Int, IO ())]
listOfFunctions = [(0, print "HI") -- notice the anonymous function
,(1, someNamedFunction) -- and something more traditional here
]
someNamedFunction = getChar >>= \x -> print x >> print x
Then we can select from this list however we want and execute the function:
executeFunctionWithVal :: Int -> IO ()
executeFunctionWithVal v = fromMaybe (return ()) (lookup v listOfFunctions)
and it works (if you import Data.Maybe):
Ok, modules loaded: Main.
> executeFunctionWithVal 0
"HI"
> executeFunctionWithVal 01
a'a'
'a'
Don't store the functions as strings, or rather, try storing the actual functions and then tagging them with a string. That way you can just call the function directly. Functions are first class values, so you can call the function using whatever name you assign it to.

Which is the most clojuresque way to compare characters and string? (single char string)

I was wondering about which is the best (clojuresque) way to compare a character and a string in Clojure.
Obviously something like that returns false:
(= (first "clojure") "c")
because first returns a java.lang.Character and "c" is a single character string. Does exists a construct to compare directly char and string without invoking a cast? I haven't found a way different from this:
(= (str (first "clojure")) "c")
but I'm not satisfied.
Any ideas?
Bye,
Alfredo
How about the straight forward String interop?
(= (.charAt "clojure" 0) \c)
or
(.startsWith "clojure" "c")
It should be as fast as it can get and doesn't allocate a seq object (and in your second example an additional string) which is immediately thrown away again just to do a comparison.
Character literals are written \a \b \c ... in Clojure so you can simply write
(= (first "clojure") \c)
strings can be directly indexed without building a sequence from then and taking the first of that sequence.
(= (nth "clojure" 0) \c)
=> true
nth calls through to this java code:
static public Object nth(Object coll, int n){
if(coll instanceof Indexed)
return ((Indexed) coll).nth(n); <-------
return nthFrom(Util.ret1(coll, coll = null), n);
}
which efficiently reads the character directly.
first call through to this java code:
static public Object first(Object x){
if(x instanceof ISeq)
return ((ISeq) x).first();
ISeq seq = seq(x); <----- (1)
if(seq == null)
return null;
return seq.first(); <------ (2)
}
which builds a seq for the string (1) (building a seq is really fast) and then takes the first item from that seq (2). after the return the seq is garbage.
Seqs are clearly the most idomatic way of accessing anything sequential in clojure and I'm not knocking them at all. It is interesting to be aware of what you are creating when. switching out all your calls to first with calls to nth is likely to be a case of premature optimization. if you want the 100th char in the string i would suggest using an indexed access function like nth
in short: don't sweat the small stuff :)
Fundamentally (at least on the Clojure level — though see Kotarak's answer and others for alternatives to this), you're comparing two sequences: "clojure" and "c". The condition of equality is that the first element of each sequence is equal. So if you want to express this directly you can do
(apply = (map first ["clojure" "c"]))
or the other way around, where you create a lazy sequence over the equality comparison between each pair of characters, and just take the first element of it:
(first (map = "clojure" "c"))
You could use the take function from clojure.contrib.string. Or write your own function that returns the first char if that's something you need frequently.
You can just use str, as you did in your second example. There isn't really anything wrong with that. I mean, you could call first on "c" as well to make it a character, but it wont really make a difference. Is there any reason why you don't like this? It's not really adding much to your code by calling str on the character.
user=> (= (subs "clojure" 0 1) "c")
true
user=> (= (str (first "clojure") "c"))
true
These days you don't necessarily have to use Java interop:
(clojure.string/starts-with? "clojure" "c")
starts-with? is just a thin wrapper (around .startsWith).
So now if you use both Clojure and ClojureScript you won't have to remember both the Java and the JavaScript interop.

Resources