<caltelt_>
johnjay: 'in c and java it's usually more like "how do i print to the screen', partially a side effect of popularity I'd think :D
vraid has quit [Ping timeout: 252 seconds]
caltelt_ has quit [Ping timeout: 245 seconds]
pierpal has joined #racket
pierpal has quit [Ping timeout: 250 seconds]
pierpal has joined #racket
<jcowan>
Sure. Lisp is a filter that weeds out low-end programmers.
<jcowan>
Chez and Stalin do well on benchmarks because they are highly optimizing AOT compilers that don't specialize in anything in particular, just in running Scheme fast.
<samth>
jcowan: any programmer can succeed with lisp
<jcowan>
Can does not equal does.
<samth>
this is also true for visual basic
ubLIX has quit [Quit: ubLIX]
dbenoit has quit [Ping timeout: 268 seconds]
Fare has joined #racket
dddddd has quit [Read error: Connection reset by peer]
notzmv has joined #racket
caltelt_ has joined #racket
ng0_ has joined #racket
Sgeo_ has joined #racket
ng0 has quit [Ping timeout: 256 seconds]
Sgeo has quit [Ping timeout: 268 seconds]
<friscosam>
johnjay: yes that's his thesis
sauvin has joined #racket
widp_ has quit [Ping timeout: 246 seconds]
pie___ has joined #racket
pie__ has quit [Ping timeout: 246 seconds]
ZombieChicken has joined #racket
endformationage has quit [Ping timeout: 272 seconds]
Sgeo has joined #racket
Sgeo_ has quit [Ping timeout: 252 seconds]
caltelt_ has quit [Ping timeout: 268 seconds]
FreeFull has quit []
ZombieChicken has quit [Ping timeout: 256 seconds]
pierpal has quit [Quit: Poof]
pierpal has joined #racket
Fare has quit [Ping timeout: 246 seconds]
lavaflow_ has quit [Read error: Connection reset by peer]
ng0_ has quit [Quit: Alexa, when is the end of world?]
soegaard has quit [Quit: soegaard]
soegaard has joined #racket
mSSM has joined #racket
vraid has joined #racket
Shambles_ has joined #racket
<Shambles_>
I am trying to solve a mental puzzle involving streams. I will do the best I can to explain it. I would appreciate help in telling me how this should be done. The ideas aren't Racket-specific but if the solution is, maybe I can still understand it.
<Shambles_>
Say I am writing a parser that accepts a stream of characters. I want to recognize tokens and skip whitespace. This implies I want to 'take' a certain number of characters from the stream, turn it into a token, skip some characters, then repeat. The problem I face is how to best do this.
<Shambles_>
There appear to be constructs for taking values and dropping them, but nothing that takes some, returns those *and* returns the remaining stream. I might have missed something, or perhaps my understanding of how to solve the problem is entirely wrong.
<soegaard>
You can use `values` to return two values at once.
<sebastianlin>
will begin0 do the trick? i kinda forgot
<Shambles_>
Values lets me return two values, but are there any basic stream functions that return 'the rest of the stream'? Is there some better way to do this?
<sebastianlin>
are you talking about `stream?` streams?
<Shambles_>
The parser is a way to describe the problem (I originally noticed this problem when trying to model what amounts to ports in what amounts to streams) but what I'm really interested in is this idea of needing a 'the chunk I asked for' and 'the rest of the stream'. Using variations on take followed by dropping the right number of elements seems really inefficient (you'd have to traverse the stream twice).
<sebastianlin>
the one provided with racket/stream
<soegaard>
So you are not per se interested in parsers?
<Shambles_>
We can talk about it in those terms. I'm actually writing something similar in another language that lacks such a concept. I noticed this problem and tried to figure out how it's supposed to be solved.
<soegaard>
Okay - I was about to say, that you ought to use ports and not streams for the parser.
<soegaard>
Instead of returning values you can do as follows:
<Shambles_>
The parser or file I/O aspect is more of a framework to discuss what I'm trying to figure out, which is that "get the useful part and the rest of the stream so you can pick up where you left off, efficiently". I figured Scheme programmers in general had solved this and I just couldn't figure out how it was done.
<soegaard>
Let all functions have two inputs: a list of tokens and the remaining stream.
<sebastianlin>
so it's not related to racket per se?
<Shambles_>
Correct. But it is related to the stream library that's in Racket and most Schemes.
<soegaard>
When a function looks at the stream, it removes characters from the stream and makes a new token.
<soegaard>
Then calls the next function and adds the new token to the list and passes the stream along.
<soegaard>
Tail recursion is your friend.
<Shambles_>
soegaard: I think I understand what you're saying. Let me try to reword it and see if I understand you right. "You loop (tail recursion) over a the stream, building up the result, then when you're done you return that result and what's left of the stream." Is that right?
<Shambles_>
Is there any way to express this idea fairly directly in SRFI 41's stream functions?
<sebastianlin>
you'll probably have to do it yourself.
<Shambles_>
I mean I can literally code that but I was assuming there would be something like a 'split under these conditions' function. It seems like this would be a common situation.
<soegaard>
Do as the romans do.
<soegaard>
Do you have examples of recursive descent parsers written in you mystery language?
<soegaard>
That would probably be the simplest to do.
<soegaard>
I would have linked to an old Scheme workshop on compilers - but I can't find it on archive.org.
<Shambles_>
The parts I was looking at and trying to figure out how to use to do this are the take(-while) and drop(-while) functions. It occurred to me that it would not be that hard to use them but it would involve two traversals which could be pretty expensive if generating the stream is expensive. Can you tell me how these would be used realistically even though they aren't useful for this task?
<Shambles_>
I can imagine using the take variety, but not the drop ones.
<Shambles_>
Oh I know how to write simple parsers yes.
<soegaard>
But streams memoize their elements - they ought to be computed only once.
<Shambles_>
The situation is this language is rather unpleasant to use but has very useful I/O facilities. I am trying to make it less unpleasant to use by building libraries on top of it that amount to a better programming language without new syntax. It has worked so far. I encountered the need to generate sequences, thought of some good reasons to do it like Scheme (e.g. no mutation so you can use the 'stream of successes' techn
<Shambles_>
Then I noticed this problem and wondered what I should do about it. I've never really thought about why the standard libraries are designed as they are.
<Shambles_>
Isn't the memoization part specific to the 'first' (value) field, not the 'rest' (next) field, so you still end up computing the 'next' nodes over and over?
<Shambles_>
I guess it could be done for both by recognizing the difference between a function and a record in the next field...
<soegaard>
No - I think. Make an experiment to test!
<Shambles_>
I'm not sure how to test this without pain.
<Shambles_>
The code is very macro heavy. I have to admit I don't understand all of SRFI 41. I understand how to use most of it, and how most of it works, but some of the 'syntax' bits, I do not understand.
<Shambles_>
Thank you for the idea at least. I believe that would be a good way to do things.
<Shambles_>
Can you think of any practical uses for drop? I guess it's only for when you want to skip every X elements?
<soegaard>
When you have peeked, you know the next elements in the stream. So one can just drop them.
<Shambles_>
So it really is intended to be used in the take X, drop X pattern?
<soegaard>
I believe so.
<Shambles_>
I see. Thanks for the help. I hope it wasn't much bother.
sebastianlin has quit [Quit: Page closed]
widp_ has joined #racket
dddddd has joined #racket
orivej_ has quit [Ping timeout: 246 seconds]
ubLIX has joined #racket
soegaard has quit [Quit: soegaard]
fmu has joined #racket
<Shambles_>
More careful reading of SRFI 41 seems to indicate both the first and rest are memoized separately. That has interesting implications about the time/space trade offs. I'm thankful you pointed that out to me.
soegaard has joined #racket
ng0 has joined #racket
widp_ has quit [Ping timeout: 250 seconds]
Fare has joined #racket
acarrico has quit [Ping timeout: 245 seconds]
soegaard has quit [Quit: soegaard]
soegaard has joined #racket
YuGiOhJCJ has joined #racket
Fare has quit [Ping timeout: 272 seconds]
soegaard has quit [Quit: soegaard]
hjek has joined #racket
hjek has quit [Remote host closed the connection]
q9929t has joined #racket
q9929t has quit [Quit: q9929t]
acarrico has joined #racket
<jcowan>
Shambles_: Yes, that' s true: it's why they are called even streams, because an unrealized stream has no non-stream objects visible at all: one must invoke either stream-car or stream-cdr to get anything realized.
<jcowan>
If you want a lighter-weight alternative, there are SRFI 121 generators and SRFI 127 lazy sequences (which would take a bit of rewrite for Racket, as they depend on mutable pairs). The latter are odd streams in the above sense: at least one element is always outside the wrapper, and car does nothing special.
ng0 has quit [Quit: Alexa, when is the end of world?]
ubLIX has quit [Quit: ubLIX]
<Shambles_>
jcowan: I don't believe generators (assuming those are the usual mutating variety) will do what I want. I'm not sure what 127 is.
<Shambles_>
The language I'm working with is very limited. I seem to have 'invented' a new kind of stream that is neither even or odd to deal with it.
<Shambles_>
There are function objects. There are no closures or macros.
<Shambles_>
I noticed the reason for even streams being preferred is to avoid calculating anything ahead of time. My solution involves passing an extra parameter along as the function object makes copies of itself. The first 'iteration' is usually treated specially. Each iteration only calculates what is necessary for it, avoiding the example's 'early division by 0'.
<Shambles_>
The advantage of this design relative to even streams is it keeps you from going insane while trying to implement it in a primitive language, and it causes errors to be detected near their cause rather than much later. The disadvantage is you can't reverse a stream of erroneous results. I consider that a pretty good trade.
<Shambles_>
So basically they're odd streams with a extra bit of 'state' (no mutation involved).
<jcowan>
121 generators are just lambdas, so they can do anything: keep state or use call/cc to yield results.
<Shambles_>
I'm thinking of calling them 'first flag streams'.
<jcowan>
A 127 lazy sequence is an improper list with a generator in its tail. You can walk down the list (which is treated as immutable) and when you get to the end, the generator is invoked and a new pair is created holding the new value in car and the generator in cdr, and linked to its predecessor.
<jcowan>
Neither involves macros of any kind. Closures, yes.
<Shambles_>
I see. I'm not sure either of those would help me. I'm also pretty uncomfortable with the existence of improper or circular lists too.
<Shambles_>
I am open to other ideas, and potentially hand-coding even streams if there is a real advantage to them, but I certainly dread trying to write functions that generate functions 'by hand' this way.
<Shambles_>
Getting a combinator library to be useful was hard enough.
orivej has joined #racket
hjek has joined #racket
ym555 has joined #racket
endformationage has joined #racket
hjek has quit [Remote host closed the connection]
notzmv has quit [Ping timeout: 250 seconds]
ZombieChicken has joined #racket
soegaard has joined #racket
aeth has quit [Ping timeout: 250 seconds]
aeth has joined #racket
<Shambles_>
jcowan: I guess the thing I came up with is very similar to lazy sequence (it only doesn't mention treating the first iteration specially), so maybe that's the name I should use. Still not sure if it's an okay way to do things.
aeth has quit [Ping timeout: 272 seconds]
aeth has joined #racket
Fare has joined #racket
Fare has quit [Ping timeout: 252 seconds]
soegaard has quit [Quit: soegaard]
lavaflow_ has quit [Read error: Connection reset by peer]
sauvin has quit [Read error: Connection reset by peer]
lavaflow_ has joined #racket
Fare has joined #racket
selimcan has joined #racket
Fare has quit [Ping timeout: 252 seconds]
hjek has joined #racket
vraid has quit [Disconnected by services]
vraid has joined #racket
Fare has joined #racket
hjek has quit [Ping timeout: 272 seconds]
widp_ has joined #racket
pera has joined #racket
Fare has quit [Ping timeout: 272 seconds]
ZombieChicken has quit [Remote host closed the connection]
ZombieChicken has joined #racket
ZombieChicken has quit [Remote host closed the connection]
ZombieChicken has joined #racket
widp_ has quit [Ping timeout: 244 seconds]
ym555 has quit [Quit: leaving...]
ng0 has joined #racket
englishm has quit [Quit: Updating details, brb]
englishm has joined #racket
englishm has quit [Excess Flood]
englishm has joined #racket
<BitPuffin>
is there a good way to extract data from a scribble document from racket?
Fare has joined #racket
<bremner>
scribble/reader provides read and read-syntax. Maybe those can help?
<BitPuffin>
yeah that's kind of what I'm thinking
<bremner>
read-syntax and syntax-parse would be my first try
<bremner>
although maybe match is just as good.
pera has quit [Ping timeout: 245 seconds]
<BitPuffin>
hmm read-syntax doesn't support #lang I think
ubLIX has joined #racket
<bremner>
hmm. is it viable for you to change the #lang line to connect to your own reader? Not that I know how...
<BitPuffin>
I think if you use read-language maybe
YuGiOhJCJ has quit [Quit: YuGiOhJCJ]
pera has joined #racket
ym555 has joined #racket
selimcan has quit [Remote host closed the connection]
selimcan has joined #racket
preschema has joined #racket
<preschema>
Hi all, I'm a Racket beginner and I was playing around with a simple macro: https://gist.github.com/adeel/ea38d812d873e74aace42bdaae62a90a It's working in the REPL but giving me an unbound identifier error when I run it normally. What am I doing wrong?
<bremner>
preschema: what's your #lang? it works ok for me in #lang racket
<preschema>
bremner: Ah, I forgot to specify, it's racket/base
rain1 has quit [Quit: WeeChat 1.6]
<bremner>
yeah, that's probably the problem
<bremner>
I forget the module name, but you need to require something
<bremner>
or use #lang racket
<preschema>
bremner: Got it! You're right, it is working with #lang racket.
widp_ has joined #racket
<greghendershott>
preschema: When using #lang racket/base, the usual incantation to write macros is `(require (for-syntax racket/base racket/syntax))`.
FreeFull has joined #racket
<preschema>
greghendershott: That's very helpful, thanks!
<greghendershott>
If you're getting started, it's probably simpler to always use `#lang racket`. Later, if you want to ship something for real, you can deal with changing to `#lang racket/base` and adding requires as needed.
rain1 has joined #racket
<preschema>
Makes sense.
selimcan has quit [Remote host closed the connection]
evdubs has quit [Remote host closed the connection]
cpup has quit [Quit: Breaking stuff]
cpup has joined #racket
<Shambles_>
jcowan: In SRFI 127, which I now notice you authored, there's a warning about potential non-termination for circular references. I can imagine how to trigger this (make instantiating the first field of the first node not terminate) but I am not sure what you had in mind or if there is a practical concern. Could you clear this up?
widp_ has quit [Ping timeout: 252 seconds]
<jcowan>
Shambles_: Here's a bit from SRFI 41: "Wadler, Taha and MacQueen show, for instance, that an expression like (stream->list 4 (stream-map / (stream-from 4 -1))) evaluates to (1/4 1/3 1/2 1) using even streams but fails with a divide-by-zero error using odd streams, because the next element in the stream, which will be 1/0, is evaluated before it is accessed."
<jcowan>
I wasn't referring to lazy sequences that are circular in the sense of circular lists: those don't exist.
<Shambles_>
My understanding of this problem is that it can be avoided if the streams are written, at the implementation level, to not compute anything ahead of time. If reading the first 4 values into the list only computes 4 divisions by 'pulling them through the divide, which only enumerates 4, 3, 2, 1 by pulling that into the divide, everything should be fine, right?
<Shambles_>
It does suppose, if it's odd streams (or anything similar) that at least 1 value will be pulled through, but presumably you want to read at least 1 value or you would not have created the stream. Or that was my thinking. Is there more to it than this?
<samth>
note that Racket streams (from racket/stream, which I recommend) allow you to get those four values from the stream
rjid has joined #racket
<Shambles_>
samth: This is for a library in another language, where I'm trying to decide how to implement a stream-like thing. The other language has no closures or macros, but does have function objects. Maybe you can understand why I am not looking forward to implementing even streams in this environment, even if it would be useful.
<Shambles_>
I can probably do it with a lot of function objects and combinators. I just dread it. I was also liking the idea of errors occurring close to their cause, which they can't do in even streams. This language also has bad tooling for debugging.
<rjid>
Hi all... I'm using #lang r5rs but have troubles using eval to evaluate expression that contain bindings not defined inside the standard environment specifiers. Could someone please give me some advice?
Fare has quit [Ping timeout: 244 seconds]
<rjid>
How is possible to "extend" the environment?
preschema has quit [Ping timeout: 268 seconds]
<Shambles_>
Isn't that just defining things or loading code into it?
<rjid>
Shambles_: it happens when i define functions not included into the (scheme-report-environment 5)
<rjid>
with (display (eval (read) (scheme-report-environment 5))))) is not possible to bind "external" definitions
<rjid>
But this is right because the binding in that environment are those defined into the r5rs
<rjid>
So i would like to extend that environment to evaluate other functions
<Shambles_>
Hmm. You're not allowed to extend the environment by evaling for example "(define f (lambda (x) x))")?
<Shambles_>
Sorry about the stray paren by the ?
<rjid>
if i do (display (eval (f 2) )) i get an arity mismatch error since eval expect an environment as second "parameter"
<rjid>
(display (eval (f 2) (scheme-report-environment 5))) works in the repl
<Shambles_>
If you maintain a reference to the environment it doesn't work, I assume?
<rjid>
let me check if i try to define the function i want to use in the repl...because now it's in a file
<rjid>
Shambles_: how is it possible to create a reference to an environment to be used later?
<Shambles_>
I would assume you would just hold the environment in a variable. Variables are just references to values, and the environment is just a value. I am not sure if 'mutable environments' are intentionally not exposed (see that Stack Overflow link) or something. I know some people want Scheme to be very static to increase its optimization potential. I haven't used eval in this way myself.
<Shambles_>
Clearly something like a mutable environment must be present for the REPL to work.
<Shambles_>
I have in toy Lisps I've written, but that's not Racket.
widp_ has quit [Ping timeout: 268 seconds]
<rjid>
so if i do (display (eval (find-symbol 'a '((((b . c) . d) e f . g) . a)) (scheme-report-environment 5))) , it works
<rjid>
but if i do: (define foo (lambda () (display (eval (read) (scheme-report-environment 5)))))
<rjid>
and after (find-symbol 'a '((((b . c) . d) e f . g) . a))
<rjid>
i get: find-symbol: undefined; cannot reference an identifier before its definition
Fare has joined #racket
<Shambles_>
Did you look at the Stack Overflow link I mentioned? It seems to be about your problem.
<Shambles_>
I believe what is going on is Racket wants to see all the definitions and compile your code before running it, all in one go. You're trying to define and run little bits at a time, which makes the big compilation up front impossible.
<Shambles_>
rjid: This is doing what I expect it to https://pastebin.com/fvFU6vNq you should be able to string together any correct number of operations inside a begin and use eval that way.
<Shambles_>
Probably not the best formatting now that I think about it but hopefully you get the idea. I'm not sure what this is for, but *usually* using eval this way is frowned upon.
<rjid>
coul you please post to some other place, i'm not able to open that link...
<rjid>
COULD
<rjid>
ops
<Shambles_>
I can try. What is causing the trouble?
<rjid>
ERR_TUNNEL_CONNECTION_FAILED
<rjid>
This site can’t be reached The webpage at https://pastebin.com/PxN20Hsp might be temporarily down or it may have moved permanently to a new web address.
<Shambles_>
Oh very odd. I'm looking at it rirght now. Do you have a preferred equivalent?
<Shambles_>
friscosam: That's what I had in mind with the 'hold the environment in a variable' comment. Looks like that also works.
<friscosam>
Yeah that's in #lang r5rs fwiw
<friscosam>
R5RS allows the scheme-report-environment to be immutable so that specific code might not be portable to other schemes
<friscosam>
Shambles_: I thought you said something to that effect... I didn't fully read all of the backscroll.
<rjid>
(define env-var (scheme-report-environment 5)) (define foo (lambda () (display (eval (read) env-var)))) ; (interaction-environment) (scheme-report-environment 5) (display (eval (find-symbol 'a '((((b . c) . d) e f . g) . a)) env-var))
<rjid>
do you mean something like that?
<rjid>
; (interaction-environment) was a comment
<rjid>
calling (foo) i get the same error
<friscosam>
what is find-symbol?
<friscosam>
If you have a small example you could share on codeshare or somesuch perhaps it will be easier to spot the problem?
<Shambles_>
rjid: The 'read' part is suspect. It looks almost like you're trying to launch a REPL (but you already have one in DrRacket...). I do not believe read will do anything useful there. You need to put the code you want to run in the first argument to eval.
<rjid>
yes
<Shambles_>
I'm not sure what you're trying to do, but we did show you how to run code via eval two different ways. If you need a REPL, you can just use the one DrRacket provides. I'm not sure if there is a way to launch another, or what the purpose in doing so would be.
<Shambles_>
And please remember that using eval this way is almost always a bad idea.
<Shambles_>
It's better to just run the code directly than call eval. It's dangerous to eval code from an untrusted source (so you shouldn't point eval at arbitrary files or the Internet).
<rjid>
ok... i will try to clarify a little bit by to myself what to do. Thank you for the help
<Shambles_>
I hope it helps. Be careful. If you're trying to deserialize something you might be better off explicitly parsing it. That will keep you from executing malicious code.
rjid has quit [Ping timeout: 256 seconds]
libertyprime has joined #racket
Fare has quit [Ping timeout: 272 seconds]
ng0 has quit [Quit: Alexa, when is the end of world?]