Arc Forumnew | comments | leaders | submitlogin
Help defining a new intra symbol for arc.
3 points by thaddeus 5381 days ago | 9 comments
Hoping I can I get a little help in defining a new intra symbol for arc.

I would like to use the '$' to expand a symbol-statement? that will coerce a string into a symbol.

I generally like to store table keys as symbols and often find I am not able to use intrasymbol expansion on a 'defop' where the arg requests are always strings. I find I do this often enough it makes sense to try changing the syntax.

for example:

before:

  (defop myapp req ()
    (let user (get user)
      (if (admin user)
	    (pr (usertable (sym user)))
	  )))
hopeful after:

  (defop myapp req ()
    (let user (get user)
      (if (admin user)
          (pr usertable$user))
    ))
Notice I don't just to a 'let user (sym (get user))' since it the same arg often also needs to be used as a string, such as in (admin user). As you can imagine if you had many args to coerce the code would be much cleaner using the after scenario. Even more so when using nested tables where the arg in question is higher up. i.e. 'usertable$user.record!time'

From what I can see, having no understanding of scheme syntax, I need to add: (insym? #\$ sym) to the second 'or' statement of:

  (define (expand-ssyntax sym)
    ((cond ((or (insym? #\: sym) (insym? #\~ sym)) expand-compose)
           ((or (insym? #\. sym) (insym? #\! sym)) expand-sexpr)
           ((insym? #\& sym) expand-and)
       ;   ((insym? #\_ sym) expand-curry)
           (#t (error "Unknown ssyntax" sym)))
     sym))
Then I need to modify 'expand-sexpr' to somehow checkfor the '$' and convert from string to symbol - this is where I am lost, and hoping someone can help...this is a little scary modifying this lower level stuff in a syntax I don't understand.

  (define (expand-sexpr sym)
    (build-sexpr (reverse (tokens (lambda (c) (or (eqv? c #\.) (eqv? c #\!)))
                                  (symbol->chars sym)
                                  '()
                                  '()
                                  #t))
                 sym))
Thanks if anyone can help. T.


2 points by fallintothis 5381 days ago | link

You can build a new expand-symbolize (or whatever) and model it after expand-sexpr, since their functions are similar.

  $ diff -u old-ac.scm ac.scm
  --- old-ac.scm  2009-08-07 17:07:47.235041122 -0700
  +++ ac.scm      2009-08-07 17:07:52.789134895 -0700
  @@ -68,6 +68,7 @@                                  
          (or (let ((c (string-ref string i)))       
                (or (eqv? c #\:) (eqv? c #\~)        
                    (eqv? c #\&)                     
  +                 (eqv? c #\$)                     
                    ;(eqv? c #\_)                    
                    (eqv? c #\.)  (eqv? c #\!)))     
              (has-ssyntax-char? string (- i 1)))))  
  @@ -90,6 +91,7 @@                                  
     ((cond ((or (insym? #\: sym) (insym? #\~ sym)) expand-compose)
            ((or (insym? #\. sym) (insym? #\! sym)) expand-sexpr)  
            ((insym? #\& sym) expand-and)                          
  +         ((insym? #\$ sym) expand-symbolize)                    
        ;   ((insym? #\_ sym) expand-curry)                        
            (#t (error "Unknown ssyntax" sym)))                    
      sym))                                                        
  @@ -167,6 +169,14 @@                                             
                                   #t))                            
                  sym))                                            
                                                                   
  +(define (expand-symbolize sym)                                  
  +  (build-symbolize (reverse (tokens (lambda (c) (eqv? c #\$))   
  +                                    (symbol->chars sym)         
  +                                    '()                         
  +                                    '()                         
  +                                    #t))                        
  +                   sym))                                        
  +                                                                
   (define (build-sexpr toks orig)                                 
     (cond ((null? toks)                                           
            'get)                                                  
  @@ -180,6 +190,20 @@                                             
                          (err "Bad ssyntax" orig)                 
                          (chars->value (car toks))))))))          
                                                                   
  +(define (build-symbolize toks orig)
  +  (cond ((null? toks)
  +         'sym)
  +        ((null? (cdr toks))
  +         (chars->value (car toks)))
  +        (#t
  +         (list (build-symbolize (cddr toks) orig)
  +               (if (eqv? (cadr toks) #\$)
  +                   (list 'sym (chars->value (car toks)))
  +                   (if (eqv? (car toks) #\$)
  +                       (err "Bad ssyntax" orig)
  +                       (chars->value (car toks))))))))
  
   (define (insym? char sym) (member char (symbol->chars sym)))
  
   (define (symbol->chars x) (string->list (symbol->string x)))
Lightly tested:

  $ mzscheme -f as.scm                       
  Use (quit) to quit, (tl) to return here after an interrupt.      
  arc> $$x
  Error: "list->string: expects argument of type <list of character>; given #\\$"
  arc> (= tbl (table))
  #hash()
  arc> (= tbl$x '(1 2 3))
  Error: "reference to undefined identifier: _x"
  arc> (= x "key")
  "key"
  arc> (= tbl$x '(1 2 3))
  (1 2 3)
  arc> tbl
  #hash((key . (1 2 3 . nil)))
  arc> tbl$x
  (1 2 3)
  arc> tbl$x.0
  1
  arc> (tbl 'x)
  nil
  arc> (tbl 'key)
  (1 2 3)
  arc> $x
  key
  arc> $x$y
  Error: "reference to undefined identifier: _y"
  arc> (= y "abc")
  "abc"
  arc> $x$y
  Error: "Function call on inappropriate object key (abc)"
  arc> :a
  $ mzscheme -i -f as.scm
  Welcome to MzScheme v4.2.1 [3m], Copyright (c) 2004-2009 PLT Scheme Inc.
  Use (quit) to quit, (tl) to return here after an interrupt.
  arc> :a
  > (ac '$x$y '())
  (ar-funcall1 (ar-funcall1 _sym (ar-funcall1 _sym _x)) (ar-funcall1 _sym _y)) ; buggy?
Scheme syntax isn't all that different from Arc syntax. The main differences you see in this example are:

- Instead of

  (def f (x) body)
in Scheme it's

  (define (f x) body)
- Different names: Arc is = Scheme eqv?, Arc t & nil = Scheme #t & #f, Arc fn = Scheme lambda, etc.

- Scheme's cond is like Arc's if, but with extra parentheses.

  ; Arc
  (if a b
      c d
        e)

  ; Scheme
  (cond (a b)
        (c d)
        (#t e))
- You have access to a different set of library functions than the ones Arc provides. Most of what you need is defined in ac.scm. If you're unsure how it works, puzzle at the definition some.

-----

2 points by thaddeus 5368 days ago | link

BTW I just got a chance to look at this tonight. I changed it a little so that $ would work with '!' and '.'

Again thanks for the help! T.

  (define (has-ssyntax-char? string i)
    (and (>= i 0)
         (or (let ((c (string-ref string i)))
               (or (eqv? c #\:) (eqv? c #\~) 
                   (eqv? c #\&)
                   (eqv? c #\$)                
                   ;(eqv? c #\_) 
                   (eqv? c #\.)  (eqv? c #\!)))
             (has-ssyntax-char? string (- i 1)))))


  (define (expand-ssyntax sym)
    ((cond ((or (insym? #\: sym) (insym? #\~ sym)) expand-compose)
           ((or (insym? #\. sym) (insym? #\! sym)(insym? #\$ sym)) expand-sexpr)
           ((insym? #\& sym) expand-and)
     ;     ((insym? #\_ sym) expand-curry)
           (#t (error "Unknown ssyntax" sym)))
     sym))

  (define (expand-sexpr sym)
    (build-sexpr (reverse (tokens (lambda (c) (or (eqv? c #\.) (eqv? c #\!)(eqv? c #\$)))
                                  (symbol->chars sym)
                                  '()
                                  '()
                                  #t))
                 sym))


  (define (build-sexpr toks orig)
    (cond ((null? toks)
           'get)
          ((null? (cdr toks))
           (chars->value (car toks)))
          (#t
           (list (build-sexpr (cddr toks) orig)
                 (cond ((eqv? (cadr toks) #\!)
                        (list 'quote (chars->value (car toks))))
                       ((eqv? (cadr toks) #\$)
                        (list 'sym (chars->value (car toks))))
                       ((or (eqv? (car toks) #\.) (eqv? (car toks) #\!)(car toks) #\$))
                         (err "Bad ssyntax" orig))
                       (#t (chars->value (car toks))))))))

-----

1 point by thaddeus 5381 days ago | link

That's great - thank you.

It'll take me a while to step through this, but I appreciate the guidance.

T.

-----

2 points by absz 5381 days ago | link

Anarki makes this easy (or it did last time I checked---this may not have been ported to Arc3, I don't recall):

  (require "ssyntaxes.arc")
  
  (= mac-dollar $)
  
  (add-ssyntax-bottom
    $ (L (sym r))
    $ mac-dollar)
(This is untested, mind you.) There's more about this on the fora somewhere, but I can't find it...

-----

2 points by thaddeus 5381 days ago | link

I avoid using anarki - after finding numerous problems running code that works with the official pg branch. And trying to understand what anarki is doing to my code when there's little documentation - it's like having a brain seizure - noob style ;).

As a per example: http://arclanguage.org/item?id=6383 ssyntax breaks 'exit-on-eof' ?

Anyway - I always try paruse anarki to learn from it since there are great code examples, but I am hesitant to jump on the anarki bandwagon.

Hoping I learn more by working through the code and trying to understand what's happening.

Thanks for the pointer though... T.

-----

1 point by rntz 5381 days ago | link

There's a reason anarki has a stable branch. Of course, it's horribly out of date now, which is why I'm (still) working on porting some of the old arc2 anarki's more useful features to arc3, without the cruft. (The delays have mostly been caused by me dithering on what the best way of handling CatDancer's idea of keeping hacks separate is; I have most of the actual features I wanted to port done already.)

-----

2 points by thaddeus 5381 days ago | link

Agreed, but if I was using anarki stable - I wouldn't have access to ssyntax.

My intent was not to disregard anarki or the work (which I know most appreciate) rather just to highlight my experiences.

-----

2 points by rntz 5381 days ago | link

It hasn't been ported to arc3.

More accurately, a) I haven't ported it to arc3 and b) it hasn't shown up on anarki's arc3 branches last I checked. If anyone else has ported it, I'd be interested to know.

-----

1 point by absz 5381 days ago | link

Good to know. I haven't done any Arc programming lately, but if I get back into it, I may take a look at the ssyntax.

-----