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.
Related
I am reading the fix-point of SICP:
#+begin_src emacs-lisp :session sicp :lexical t
(defvar tolerance 0.00001)
(defun fixed-point(f first-guess)
(defun close-enoughp(v1 v2)
(< (abs (- v1 v2)) tolerance))
(defun try(guess) ;;
(let ((next (funcall f guess)))
(if (close-enoughp guess next)
next
(try next))))
(try first-guess))
(fixed-point #'cos 1.0)
#+end_src
#+RESULTS:
: 0.7390822985224024
From the above case, I learned that one nature of while is the abstract concept "try"
#+begin_src ipython :session sicp :results output pySrc/sicp_fixedpoint2.py
import math
def fixed_point(f, guess):
while True:
nex = f(guess)
if abs(guess-nex) < 0.0001:
return nex
else:
guess = nex #local assignment is nature of lambda
print(fixed_point(math.cos, 1))
#+end_src
#+RESULTS:
: 0.7390547907469174
So I could write iteration in python just with the effective functional abstraction thinking.
When reflect on try, more than "try is a while in iteration", what it teach me?
It could be reframed without try, but return return fixed_point(f, nex) directly.
#+begin_src ipython :session sicp :results output :tangle pySrc/sicp_fixedpoint.py
import math
tolerance = 0.00001
def fixed_point(f, guess):
def good_enoughp(a, b):
return abs(a-b) < tolerance
nex = f(guess)
if good_enoughp(guess, nex):
return nex
else:
return fixed_point(f, nex)
print(fixed_point(math.cos, 1))
#+end_src
#+RESULTS:
: 0.7390822985224024
So why SICP introduced try here, I guess efficiency might not be the author's key consideration.
Test with elisp
#+begin_src emacs-lisp :session sicp :lexical t
(defvar tolerance 0.00001)
(defun fixed-point(f guess)
(defun close-enoughp(v1 v2) ;
(< (abs (- v1 v2)) tolerance))
(let ((next (funcall f guess)))
(if (close-enoughp guess next)
next
(fixed-point f next)))
)
;;(trace-function #'fixed-point)
(fixed-point #'cos 1.0)
#+end_src
#+RESULTS:
: 0.7390822985224024
It works as expected.
It seems that return fixed-point f next is a bit cleaner than a inner iteration with try.
What's the consideration of SICP here, what was intended to teach?
It's the opposite: it's cleaner and more efficient with try because it doesn't need to redefine the good-enough-p.
(also, you're not supposed to use recursion in Python).
The version with try is better than the version which calls the top function, fixed-point, because fixed-point contains inner definitions, of the functions good-enough-p and try. A simple-minded compiler would compile it so that on each call it actually makes those definitions anew, again and again, on each call. With try there's no such concern as it is already inside the fixed-point's inner environment where good-enough-p is already defined, and so try can just run.
(correction/clarification: the above treats your code as if it were Scheme, with internal defines instead of the Common Lisp with defuns as you show. SICP is Scheme, after all. In Common Lisp / ELisp there's not even a question -- the internal defuns will always be performed, on each call to the enclosing function, just (re)defining the same functions at the top level over and over again.)
Incidentally, I like your Python loop translation, it is a verbatim translation of the Scheme's tail-recursive loop, one to one.
Your while translation is exactly what a Scheme compiler is supposed to be doing given the first tail-recursive Scheme code in your question. The two are exactly the same, down to the "horrible while True ... with an escape" which, personally, I quite like for its immediacy and clarity. Meaning, I don't need to keep track of which value gets assigned to what variable and which variable gets returned in the end -- instead, a value is just returned, just like it is in Scheme.
The natural way to write something like this in Python is something like this, I think:
tolerance = 0.00001
def fixed_point(f, first_guess):
guess = first_guess
next_guess = f(guess)
def close_enough(a, b):
return (abs(a - b) < tolerance)
while not close_enough(guess, next_guess):
guess = next_guess
next_guess = f(guess)
return next_guess
This:
uses a while loop rather than recursion in the way that is natural in Python;
doesn't use some horrible while True ... with an escape which is just confusing.
(In fact, since function-call in Python is generally very slow, it is probably more natural to open-code the call to close_enough and remove the local function altogether.)
But this is imperative code: it's full of assignment (the first two 'assignments' are really bindings of variables as Python doesn't distinguish the two syntactically, but the later assignments really are assignments). We want to express this in a way which doesn't have assignment. We also want to replace it by something which does not use any looping constructs or expresses those looping constructs in terms of function calls.
We can do this in two ways:
we can treat the top-level function as the thing we call recursively;
we can define some local function through which we recurse.
Which of these we do is really a choice, and in this case it probably makes little difference. However there are often significant advantages to the second approach: in general the top-level function (the function that is in some interface we might be exposing to people) may have all sorts of extra arguments, some of which may have default values and so on, which we really don't want to have to keep passing through the later calls to it; the top-level function may also just not have an appropriate argument signature at all because the iterative steps may be iterating over some set of values which are derived from the arguments to the top-level function.
So, it's generally better to express the iteration in terms of a local function although it may not always be so.
Here is a recursive version in Python which takes the chance to also make the signature of the top-level function sightly richer. Note that this approach would be terrible style in Python since Python does not do anything special with tail calls. The code is also littered with returns because Python is not an expression language (don't believe people who say 'Python is like Lisp': it's not):
default_tolerance = 0.00001
def fixed_point(f, first_guess, tolerance=default_tolerance):
guess = first_guess
next_guess = f(guess)
def close_enough(a, b):
return (abs(a - b) < tolerance)
def step(guess, next_guess):
if close_enough(guess, next_guess):
return next_guess
else:
return step(next_guess, f(next_guess))
return step(first_guess, f(first_guess))
Well, in Scheme this is much more natural: here is the same function written in Scheme (in fact, in Racket):
(define default-tolerance 0.00001)
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(define (try guess next)
(if (close-enough? guess next)
next
(try next (f next))))
(try initial-guess (f initial-guess)))
The only thing that is annoying about this is that we have to kick-off the iteration after defining try. Well, we could avoid even that with a macro:
(define-syntax-rule (iterate name ((var val) ...) form ...)
(begin
(define (name var ...)
form ...)
(name val ...)))
And now we can write the function as:
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(iterate try ((guess initial-guess) (next (f initial-guess)))
(if (close-enough? guess next)
next
(try next (f next)))))
Well, in fact we don't need to write this iterate macro: it's so useful in Scheme that it already exists as a special version of let called 'named let':
(define (fixed-point f initial-guess #:tolerance (tolerance default-tolerance))
(define (close-enough? v1 v2)
(< (abs (- v1 v2)) tolerance))
(let try ((guess initial-guess) (next (f initial-guess)))
(if (close-enough? guess next)
next
(try next (f next)))))
And with any of these versions:
> (fixed-point cos 0)
0.7390822985224023
> (fixed-point cos 0 #:tolerance 0.1)
0.7013687736227565
Finally a meta-comment: I don't understand why you seem to be trying to learn Scheme using Emacs Lisp. The two languages are not alike at all: if you want to learn Scheme, use Scheme: there are probably hundreds of Scheme systems out there, almost all of which are free.
Scheme permits redefinition of top-level symbols, such as fixed-point; even the function f could redefine it! Compilers (and interpreters) need to take this into consideration, and check for a redefinition every call of fixed-point. On the other hand, try is not visible outside the definition of fixed-point, so f cannot redefine it. So, the compiler (or interpreter) can turn this tail recursive function into a loop.
i need to retrieve the key whose value contains a string "TRY"
:CAB "NAB/TRY/FIGHT.jar"
so in this case the output should be :CAB .
I am new to Clojure, I tried a few things like .contains etc but I could not form the exact function for the above problem.its easier in few other languages like python but I don't know how to do it in Clojure.
Is there a way to retrieve the name of the key ?
for can also filter with :when. E.g.
(for [[k v] {:FOO "TRY" :BAR "BAZ"}
:when (.contains v "TRY")]
k)
First, using .contains is not recommended - first, you are using the internals of the underlying language (Java or JavaScript) without need, and second, it forces Clojure to do a reflection as it cannot be sure that the argument is a string.
It's better to use clojure.string/includes? instead.
Several working solutions have been already proposed here for extracting a key depending on the value, here is one more, that uses the keep function:
(require '[clojure.string :as cs])
(keep (fn [[k v]] (when (cs/includes? v "TRY") k))
{:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"}) ; => (:CAB)
The easiest way is to use the contains method from java.lang.String. I'd use that to map valid keys, and then filter to remove all nil values:
(filter some?
(map (fn [[k v]] (when (.contains v "TRY") k))
{:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"}))
=> (:CAB)
If you think there is at most one such matching k/v pair in the map, then you can just call first on that to get the relevant key.
You can also use a regular expression instead of .contains, e.g.
(fn [[k v]] (when (re-find #"TRY" v) k))
You can use some on your collection, some will operate in every value in your map a given function until the function returns a non nil value.
We're gonna use the function
(fn [[key value]] (when (.contains values "TRY") key))
when returns nil unless the condition is matched so it will work perfectly for our use case. We're using destructuring in the arguments of the function to get the key and value. When used by some, your collection will indeed be converted to a coll which will look like
'((:BAR "NAB/TRY/FIGHT.jar"))
If your map is named coll, the following code will do the trick
(some
(fn [[key value]] (when (.contains value "TRY") key))
coll)
My program currently writes bytes using write-byte throughout the program.
When there is an error in the program, the program stops there but I've realized that this still leaves the previously written bytes (before encountering the error).
I was wondering if it is possible to hold on to all the bytes that I want to output until the successful ending of the program so that if the program encounters an error before the end of the program, it outputs nothing, and if no error is encountered, then I can output all the bytes that I wanted to write.
You can wrap your program in with-output-to-bytes to produce a bytestring value instead of writing directly to stdout:
(with-output-to-bytes
(λ ()
(write-bytes #"a")
(write-bytes #"b")))
Internally, this is just a super simple wrapper around open-output-bytes and a parameterization of current-output-port, so if you want more fine-grained control, you can use those directly. For example, if you have a simple script and don’t want to wrap the whole program, you can mutate the current-output-port parameter globally:
(define stdout (current-output-port))
(define output (open-output-bytes))
(current-output-port output)
(void
(begin
(write-bytes #"a")
(write-bytes #"b")))
(write-bytes (get-output-bytes output) stdout)
However, be careful: mutating current-output-port like that will affect everything that prints, including the output from expressions evaluated at a module level, which is why it is necessary to wrap the write-bytes invocations with void above.
One can add bytes to a list and print them together later:
(define lst '())
(set! lst (cons #"a" lst))
(set! lst (cons #"b" lst))
(println lst)
(for ((item (reverse lst)))
(write-bytes item))
Output:
'(#"b" #"a")
ab
List has to be reversed since 'cons' adds item to the head of the list.
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
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.