[racket-users] how to `read-char` from port using `latin-1` encoding?

2017-03-31 Thread Matthew Butterick
IIUC when `read-char` reads from a port it assumes the port uses UTF-8 
encoding. [1] 

(My Racketuition suggests there might be a parameter called 
`current-port-encoding` that controls what encoding is applied to the port, but 
apparently not.)

So instead, one must convert the port explicitly. OK, this seems to work:

(open-input-string (bytes->string/latin-1 (port->bytes port)))

The problem is that I'm reading all the bytes first, which defeats the 
port-ishness of the operation.

But if I try the promising-sounding `reencode-input-port`:

(reencode-input-port port "latin-1")

This doesn't work, because it relies on `bytes-open-converter`, which 
apparently doesn't know about `latin-1` encoding (a teeny bit surprising since 
other racket/base functions deal with this encoding)

Hence the question: is there a smarter way to read characters from a `latin-1` 
encoded port?


[1] http://docs.racket-lang.org/reference/encodings.html?q=encoding 


-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Reporting exceptions as though they came from the caller

2017-03-31 Thread David Storrs
Imagine I have the following trivial module (ignore that things are defined
out of sequence for clarity):

#lang racket

(define (foo arg)
(_baz arg)  ; do some checking, raise an exception if there's a problem
...do stuff...
)

(define (bar arg)
(_baz arg)  ; do some checking, raise an exception if there's a problem
...do stuff)

(define (_baz arg)  ; internal helper function
(when (equal? arg "bad value")
(raise-arguments-error '_baz "got a bad value" "val" val))) ;; <===
report is from _baz, not foo or bar

(provide foo bar)


In Perl I can use caller() [1] to access the stack so that I can have _baz
report errors as though the error were coming from 'foo' or 'bar' as
appropriate -- which is what the user expects to see, since their code
called 'foo' or 'bar', not '_baz'.  (Even better, I could report as though
the error were coming from the *caller* of foo / bar, which is the user's
actual code and the real source of the problem.) How can I do the same in
Racket?  I see the errortrace library, but that says "don't install this
into a module and expect it to work."

I could pass the name down, of course, but that's clumsy.  I could also
create a parameter and set it every time I call the helper function that
needs it, but that's even more clumsy / action-at-a-distance-y and easy to
forget.  What's the right way?


[1] https://perldoc.perl.org/functions/caller.html

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] how to `read-char` from port using `latin-1` encoding?

2017-03-31 Thread Matthew Flatt
Try "latin1" (no hyphen).

I'm not sure of the standard for these names, but probably Racket's `latin-1` 
functions are misnamed.

> On Mar 31, 2017, at 3:55 PM, Matthew Butterick  wrote:
> 
> IIUC when `read-char` reads from a port it assumes the port uses UTF-8 
> encoding. [1] 
> 
> (My Racketuition suggests there might be a parameter called 
> `current-port-encoding` that controls what encoding is applied to the port, 
> but apparently not.)
> 
> So instead, one must convert the port explicitly. OK, this seems to work:
> 
> (open-input-string (bytes->string/latin-1 (port->bytes port)))
> 
> The problem is that I'm reading all the bytes first, which defeats the 
> port-ishness of the operation.
> 
> But if I try the promising-sounding `reencode-input-port`:
> 
> (reencode-input-port port "latin-1")
> 
> This doesn't work, because it relies on `bytes-open-converter`, which 
> apparently doesn't know about `latin-1` encoding (a teeny bit surprising 
> since other racket/base functions deal with this encoding)
> 
> Hence the question: is there a smarter way to read characters from a 
> `latin-1` encoded port?
> 
> 
> [1] http://docs.racket-lang.org/reference/encodings.html?q=encoding
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] how to `read-char` from port using `latin-1` encoding?

2017-03-31 Thread Jon Zeppieri
Try using "iso-8859-1" as the name of the encoding, instead of "latin-1." -J


On Fri, Mar 31, 2017 at 3:55 PM, Matthew Butterick  wrote:
> IIUC when `read-char` reads from a port it assumes the port uses UTF-8
> encoding. [1]
>
> (My Racketuition suggests there might be a parameter called
> `current-port-encoding` that controls what encoding is applied to the port,
> but apparently not.)
>
> So instead, one must convert the port explicitly. OK, this seems to work:
>
> (open-input-string (bytes->string/latin-1 (port->bytes port)))
>
> The problem is that I'm reading all the bytes first, which defeats the
> port-ishness of the operation.
>
> But if I try the promising-sounding `reencode-input-port`:
>
> (reencode-input-port port "latin-1")
>
> This doesn't work, because it relies on `bytes-open-converter`, which
> apparently doesn't know about `latin-1` encoding (a teeny bit surprising
> since other racket/base functions deal with this encoding)
>
> Hence the question: is there a smarter way to read characters from a
> `latin-1` encoded port?
>
>
> [1] http://docs.racket-lang.org/reference/encodings.html?q=encoding
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] how to `read-char` from port using `latin-1` encoding?

2017-03-31 Thread Matthew Butterick
OK thanks. Both "latin1" and "iso-8859-1" do work with `reencode-input-port`.



> On Mar 31, 2017, at 1:08 PM, Jon Zeppieri  wrote:
> 
> Try using "iso-8859-1" as the name of the encoding, instead of "latin-1." -J
> 
> 
> On Fri, Mar 31, 2017 at 3:55 PM, Matthew Butterick  wrote:
>> IIUC when `read-char` reads from a port it assumes the port uses UTF-8
>> encoding. [1]
>> 
>> (My Racketuition suggests there might be a parameter called
>> `current-port-encoding` that controls what encoding is applied to the port,
>> but apparently not.)
>> 
>> So instead, one must convert the port explicitly. OK, this seems to work:
>> 
>> (open-input-string (bytes->string/latin-1 (port->bytes port)))
>> 
>> The problem is that I'm reading all the bytes first, which defeats the
>> port-ishness of the operation.
>> 
>> But if I try the promising-sounding `reencode-input-port`:
>> 
>> (reencode-input-port port "latin-1")
>> 
>> This doesn't work, because it relies on `bytes-open-converter`, which
>> apparently doesn't know about `latin-1` encoding (a teeny bit surprising
>> since other racket/base functions deal with this encoding)
>> 
>> Hence the question: is there a smarter way to read characters from a
>> `latin-1` encoded port?
>> 
>> 
>> [1] http://docs.racket-lang.org/reference/encodings.html?q=encoding
>> 
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Typing lag with DrRacket on Linux

2017-03-31 Thread Dave Musicant
Hey folks,

I'm using DrRacket on a 64-bit Ubuntu 16.04 system with the default Unity 
windowing system, and am finding that typing in the definitions window is 
laggy. The problem isn't a show-stopper, as it keeps up more or less as I type, 
but it's disorienting. I teach a class using DrRacket, and I had the experience 
today of coding in front of the class and the lag was just disorienting enough 
that I kept making typos I don't usually make. It's a psychological thing. 
That, and when I hold down a cursor key to quickly move through the program and 
then let go, the cursor keeps moving for a while from buffered keystrokes.  If 
I give it a good burst of typing, I can sit back and watch the text fill in 
while I wait. I don't see this behavior in other programs (terminal windows, 
text editors, etc.)

I've tried both version 6.3 (in the Ubuntu repos) and 6.8 (downloaded from 
racket-lang.org).

I've have tried turning off incremental syntax checking and background 
expansion. No significant effect. What does matter is the size of the window. 
If I shrink the DrRacket window, typing lag goes away. So, I can solve the 
problem by making the window significantly smaller than I'd like, but of 
course, I'd prefer to run maximized. I'm running on a Lenovo Thinkpad t460s at 
native resolution, which is 1920x1080. I'm otherwise running at Ubuntu defaults 
on the display settings, as far as I know. I typically set menu/title-bar 
scaling to 1.25, but I've verified that the same behavior persists in DrRacket 
if I drop that scaling back down to 1.

Any thoughts on how this might be resolved?

Thanks, much appreciated.

--
Dave Musicant

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Reporting exceptions as though they came from the caller

2017-03-31 Thread Ryan Culpepper

On 03/31/2017 04:00 PM, David Storrs wrote:

Imagine I have the following trivial module (ignore that things are
defined out of sequence for clarity):

#lang racket

(define (foo arg)
(_baz arg)  ; do some checking, raise an exception if there's a problem
...do stuff...
)

(define (bar arg)
(_baz arg)  ; do some checking, raise an exception if there's a problem
...do stuff)

(define (_baz arg)  ; internal helper function
(when (equal? arg "bad value")
(raise-arguments-error '_baz "got a bad value" "val" val))) ;;
<=== report is from _baz, not foo or bar

(provide foo bar)


In Perl I can use caller() [1] to access the stack so that I can have
_baz report errors as though the error were coming from 'foo' or 'bar'
as appropriate -- which is what the user expects to see, since their
code called 'foo' or 'bar', not '_baz'.  (Even better, I could report as
though the error were coming from the *caller* of foo / bar, which is
the user's actual code and the real source of the problem.) How can I do
the same in Racket?  I see the errortrace library, but that says "don't
install this into a module and expect it to work."

I could pass the name down, of course, but that's clumsy.  I could also
create a parameter and set it every time I call the helper function that
needs it, but that's even more clumsy / action-at-a-distance-y and easy
to forget.  What's the right way?


You've just described the two ways that I know of. I call the first one 
"WHO-passing style", and I use it a lot. I agree, it's a bit cumbersome.


A few years ago I experimented with taking the idea to the extreme. I 
wound up with something like this:


(define (foo x y #:who [who 'foo])
   (when  (error who "something bad happened"))
   (bar z #:who who) )

Within a library, every function that might raise an error has an 
optional #:who argument. Every direct call to another such function in 
the same library passes along the current who argument. Finally, the 
main module provides the entry point functions with contracts that omit 
the #:who argument.


It might be a fun macro exercise to make a special definition form that 
automates "WHO-passing style", if anyone is interested :)


--

The parameter approach is difficult to get right. Here are two test 
cases. For both, assume there are two "entry point" functions, foo and bar.


1. If foo calls bar, and bar raises an error, the error should appear to 
come from foo. (Because that's the function the client called directly.)


2. If foo takes a procedure argument, and that procedure (originating 
from the client) calls bar, and bar raises an error, the error should 
appear to come from bar. (Even though the client called foo first and 
foo has not yet returned, control passed back to the client, and the 
error was triggered by a separate call to bar.)


The contract system already deals with the notion of boundaries between 
parties. Maybe there's a way to extend it to provide a more satisfactory 
solution to this problem.


Ryan

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Reporting exceptions as though they came from the caller

2017-03-31 Thread Jon Zeppieri
On Fri, Mar 31, 2017 at 4:00 PM, David Storrs  wrote:
> Imagine I have the following trivial module (ignore that things are defined
> out of sequence for clarity):
>
> #lang racket
>
> (define (foo arg)
> (_baz arg)  ; do some checking, raise an exception if there's a problem
> ...do stuff...
> )
>
> (define (bar arg)
> (_baz arg)  ; do some checking, raise an exception if there's a problem
> ...do stuff)
>
> (define (_baz arg)  ; internal helper function
> (when (equal? arg "bad value")
> (raise-arguments-error '_baz "got a bad value" "val" val))) ;; <===
> report is from _baz, not foo or bar
>
> (provide foo bar)
>
>
> In Perl I can use caller() [1] to access the stack so that I can have _baz
> report errors as though the error were coming from 'foo' or 'bar' as
> appropriate -- which is what the user expects to see, since their code
> called 'foo' or 'bar', not '_baz'.  (Even better, I could report as though
> the error were coming from the *caller* of foo / bar, which is the user's
> actual code and the real source of the problem.) How can I do the same in
> Racket?  I see the errortrace library, but that says "don't install this
> into a module and expect it to work."
>
> I could pass the name down, of course, but that's clumsy.  I could also
> create a parameter and set it every time I call the helper function that
> needs it, but that's even more clumsy / action-at-a-distance-y and easy to
> forget.  What's the right way?
>
>
> [1] https://perldoc.perl.org/functions/caller.html
>


Depending on your exact situation, you may be able to get the contract
system to do the work for you. A non-trivial example from actual code:

In the Gregor library, there are a number of constructors that accept
year, month, and day arguments. All of them need to ensure that the
combination refers to an actual day. Instead of having each use code
like:

 (if (date-exists? year month day)
   (something-useful)
   (raise-bad-date ...))

those functions all have contracts like:

```
[date (->i ([year exact-integer?])
   ([month (integer-in 1 12)]
[day (year month) (day-of-month/c year month)])
   [d date?])]
```

The most interesting argument contract there is `day-of-month/c`,
which checks the `day` argument, but depends on both `year` and
`month`, as well.

`day-of-month/c` is defined like this:

```
(define (day-of-month/c y m)
  (integer-in 1 (days-in-month y m)))
```
Where `days-in-month` does what you would expect.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Reporting exceptions as though they came from the caller

2017-03-31 Thread WarGrey Gyoudmon Ju
I use continuation marks to extract the nearest named function (named loops
are also contained in the context):

(define-syntax (#%function stx) ; class method has a symbol name looks like
"[name] method in [class%]"
  #'(let use-next-id : Symbol ([stacks (continuation-mark-set->context
(current-continuation-marks))])
  (if (null? stacks) 'λ
  (or (caar stacks)
  (use-next-id (cdr stacks))

with

(define-syntax (throw stx)
  (syntax-parse stx
[(_ st:id rest ...)
 #'(throw [st] rest ...)]
[(_ [st:id argl ...] frmt:str v ...)
 #'(throw [st argl ...] (#%function) frmt v ...)]
[(_ [st:id argl ...] src frmt:str v ...)
 #'(raise (st (format (string-append "~s: " frmt) src v ...)
(current-continuation-marks) argl ...))]))

this macro works much like `error`, and it allows you passing additional
arguments if the exception has more arguments:

(define (throw-exn) : Nothing
(throw [exn:fail:network:errno (cons 1 'posix)] "message: ~a" (gensym)))

On Sat, Apr 1, 2017 at 4:00 AM, David Storrs  wrote:

> Imagine I have the following trivial module (ignore that things are
> defined out of sequence for clarity):
>
> #lang racket
>
> (define (foo arg)
> (_baz arg)  ; do some checking, raise an exception if there's a problem
> ...do stuff...
> )
>
> (define (bar arg)
> (_baz arg)  ; do some checking, raise an exception if there's a problem
> ...do stuff)
>
> (define (_baz arg)  ; internal helper function
> (when (equal? arg "bad value")
> (raise-arguments-error '_baz "got a bad value" "val" val))) ;;
> <=== report is from _baz, not foo or bar
>
> (provide foo bar)
>
>
> In Perl I can use caller() [1] to access the stack so that I can have _baz
> report errors as though the error were coming from 'foo' or 'bar' as
> appropriate -- which is what the user expects to see, since their code
> called 'foo' or 'bar', not '_baz'.  (Even better, I could report as though
> the error were coming from the *caller* of foo / bar, which is the user's
> actual code and the real source of the problem.) How can I do the same in
> Racket?  I see the errortrace library, but that says "don't install this
> into a module and expect it to work."
>
> I could pass the name down, of course, but that's clumsy.  I could also
> create a parameter and set it every time I call the helper function that
> needs it, but that's even more clumsy / action-at-a-distance-y and easy to
> forget.  What's the right way?
>
>
> [1] https://perldoc.perl.org/functions/caller.html
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Reporting exceptions as though they came from the caller

2017-03-31 Thread Matthew Butterick

> On Mar 31, 2017, at 1:00 PM, David Storrs  wrote:
> 
> In Perl I can use caller() [1] to access the stack so that I can have _baz 
> report errors as though the error were coming from 'foo' or 'bar' as 
> appropriate -- which is what the user expects to see, since their code called 
> 'foo' or 'bar', not '_baz'.  (Even better, I could report as though the error 
> were coming from the *caller* of foo / bar, which is the user's actual code 
> and the real source of the problem.) 

An exception propagates upward through the calling chain. So rather than 
immediately using `raise-arguments-error` and launching it to the top, you 
could raise the error in two steps:

1) create a new error type (say, `(struct _baz-error (msg))`, so it has a 
unique predicate). You can also inherit from something in the `exn` hierarchy.

2) raise this error within `_baz`: `(raise (_baz-error "whoops"))`

3) catch the error within `foo` or `bar` using `with-handlers`:

`(with-handlers ([_baz-error? (λ (exn) (handle-baz-error exn)])
   ···)`

Where `handle-baz-error` maybe re-raises the error with `raise-argument-errors` 
using the name of the current function.

4) Or following your "even better" idea, put the `with-handlers` in the caller 
of `foo` / `bar`.

Here's an example of this approach:

http://beautifulracket.com/basic-2/better-line-errors.html 


5) You could extend this idea to more than two steps, where you collect other 
names in the calling chain on the way up.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.