elyandarin
2019-11-30 15:10:20

Hm, so, I think this is probably a very basic question, but I’m not sure.

I want my tokenizer to use “lexer-src-pos” normally, for debugging purposes, but to just use “lexer” when I tell it to, because that way, test cases are simpler to write. Using an optional "#:simpler" argument with a lambda form seems like the way to tell the program to distinguish the cases, but I’m fuzzy about how to proceed next. I’ve gotten the impression that lisp languages are more flexible about modifying code, so there’s probably a way that I can just replace “lexer-src-pos” with an expression that chooses dynamically what function to use in that position? How should I in the simplest way make the function switch between using “lexer” and “lexer-src-pos”?


soegaard2
2019-11-30 15:12:36

(define debug? #t) (define lex (if debug? lexer-src-pos lexer)) (lex "an interesting string")


soegaard2
2019-11-30 15:14:41

But … why not use lexer-src-pos always?


elyandarin
2019-11-30 15:27:31

Well, lexer-src-pos gives more data, unnecessary for checking test cases. I suppose I could make something to cut away the redundant data, but it seemed easier to fix it at the source - and also it’s an opportunity to get more familiar with coding Racket in that way.


elyandarin
2019-11-30 16:32:01

Hm, this doesn’t seem to work. Says “bad syntax in lexer”. I made a test case work just fine with this syntax, switching between “print” and “println” on command, so I think it’s something about the lexer that does it. #lang br/quicklang (require brag/support) (define test (lambda (text #:break? [break? #f]) (define customprint (if break? println print)) (define lex (if break? lexer lexer-src-pos)) (customprint text) (customprint text) )) (test "hi") (test "hi" #:break? #t)


soegaard2
2019-11-30 16:34:55

Ah. I misrembered, I thought lexer and lexer-src-pos were functions, but they are not.


soegaard2
2019-11-30 16:38:50

How about: (define lex/src (lexer-src-pos ...)) (define (lex in) (position-token-token (lex/src in)) Then lex/src and lex are functions, and now (define my-lex (if break? lex lex/src)) will work.


elyandarin
2019-11-30 16:40:38

I’ll try it out. Thanks!


laurent.orseau
2019-11-30 16:44:28

There’s a regexp replace quickscript in the quickscript-extra package, and one predefined template does just that


laurent.orseau
2019-11-30 16:46:23

Need to say that it replaces within the selected text only


elyandarin
2019-11-30 16:50:42

Hm, looks like it objects to the ellipsis. #lang br/quicklang (require brag/support) (define test (lambda (text #:break? [break? #f]) (define customprint (if break? println print)) (define lex/src (lexer-src-pos ...)) (define (lex in) (position-token-token (lex/src in))) (define my-lex (if break? lex lex/src)) (customprint text) (customprint text) )) unsaved editor:6:33: lexer-src-pos: not a regular expression / action pair at: … in: (lexer-src-pos …) #(175 3)


soegaard2
2019-11-30 16:51:07

The ellipsis is a placeholder for your grammar rules.


elyandarin
2019-11-30 16:51:16

ah, OK


soegaard2
2019-11-30 16:52:03

The idea is to make one lexer lex/src that produces tokens with source locations. And then make a new lexer lex that calls lex/src and just throws away the source locations.


soegaard2
2019-11-30 16:52:25

In this way you only need your grammar rules in one place.


laurent.orseau
2019-11-30 16:58:47

Otherwise for this particular task it’s also very simple to write your own quickscript, since the default input of the script is the selected text and the output is the replacement string, so it’s just a matter of calling string-trim. Edit: see code below


elyandarin
2019-11-30 17:14:24

This one almost worked! …maybe I should just edit the output. Seems easier at this point. If this new wrinkle is fixable, though, I will have learned something new and interesting.

OK, so the new problem is that the relevant code piece goes: (apply-tokenizer-maker make-tokenizer script1) where make-tokenizer is the function I just edited. So I’m just feeding the function to the program that calls it, and there’s nowhere I can put the optional parameter I spent all this time putting in…

So, is there a thing I can do where I tell apply-tokenizer “oh, and when you call make-tokenizer, also give it this parameter”? (In the program language I’m writing, I’ll definitely make a point of adding that functionality…)


sorawee
2019-11-30 17:15:43

You can use parameters


sorawee
2019-11-30 17:15:56

See make-parameter and parameterize


elyandarin
2019-11-30 17:16:21

thanks, I’ll check it out!



sorawee
2019-11-30 17:27:10

@elyandarin alternatively, you can curry your make-tokenizer .

(define (make-tokenizer option) (lambda (... original-arguments ...) ... do-something-with-option ...)) ;; equivalently, you can use a short-hand form: (define ((make-tokenizer option) ... original-arguments ...) ... do-something-with-option ...) (apply-tokenizer-maker (make-tokenizer your-option-here) script1)


samdphillips
2019-11-30 18:04:46

I’ve normally just use the lexer with all of the source information, but just don’t test that part.


samdphillips
2019-11-30 18:05:09

samdphillips
2019-11-30 18:06:48

Thanks


gfb
2019-11-30 21:13:59

Is there a reason ~? should be restricted to one or two expressions? Regardless of that answer, is there a good way to currently express the higher-arity version (without unrolling it) : I’m exposing a restricted macro system and the higher-arity version would cover a lot of the intended case-based behaviour (without, for example, exposing and thus parenthesis grouping multiple pattern-template clauses).


notjack
2019-12-1 00:13:43

@gfb That’s a neat idea. Could you describe your restricted macro system more?


gfb
2019-12-1 01:47:39

@notjack It’s probably not particularly exciting out-of-context. I’ve made a teaching language for an introductory course, lean heavily on algebraic stepping with some custom algebraic rules, and on the last day would like talk about syntactic sugar (mainly to get them halfway to other languages, e.g. loops, python list comprehensions, R tidyverse piping, etc). So I’ve got a little macro called shorthand wrapping define-simple-macro, export a wrapper around expand-once to see that as us adding an algebraic rule that happens at compile-time, export a pattern-expander that’s a hybrid of ~or* / ~optional / ~seq that covers enough interesting examples without having all three independently, and export ~? but would like something close to the dual of that hybrid pattern expander. If that’s still of interest, I’ll come back and link to the details after the lecture.


rod
2019-12-1 03:02:57

@rod has joined the channel


sorawee
2019-12-1 05:19:38

In DrRacket, if I choose “Enable automatic parentheses, square brackets, and quotes”, I can select a text and type ( to put parentheses around the text. However, if I type [ , [] will replace the text. Is there a way to make the behavior similar to ( ? Also, is this considered a bug?