Perl in Scheme: A DSL Abram Hindle Kitchener/Waterloo Perl Mongers - - PowerPoint PPT Presentation

perl in scheme a dsl
SMART_READER_LITE
LIVE PREVIEW

Perl in Scheme: A DSL Abram Hindle Kitchener/Waterloo Perl Mongers - - PowerPoint PPT Presentation

Perl in Scheme: A DSL KW.PM 2007/10 Perl in Scheme: A DSL Abram Hindle Kitchener/Waterloo Perl Mongers Canada http://kw.pm.org/ { abez+kw } @abez.ca Abram Hindle 1 Perl in Scheme: A DSL KW.PM 2007/10 Overview Motivation Scheme


slide-1
SLIDE 1

Perl in Scheme: A DSL KW.PM 2007/10

Perl in Scheme: A DSL

Abram Hindle

Kitchener/Waterloo Perl Mongers Canada http://kw.pm.org/

{abez+kw}@abez.ca

Abram Hindle 1

slide-2
SLIDE 2

Perl in Scheme: A DSL KW.PM 2007/10

Overview

  • Motivation
  • Scheme Intro
  • DSL
  • Conclusions

Abram Hindle 2

slide-3
SLIDE 3

Perl in Scheme: A DSL KW.PM 2007/10

Introduction

  • I like Scheme
  • Scheme is a tiny but powerful language
  • Scheme’s liberal syntax and macro language allows it

to be very flexible

  • Scheme has a different style for implementing tasks
  • Sometimes I have solved the problem already in Perl

– But I’m working in Scheme!

∗ Sometimes vice versa

Abram Hindle 3

slide-4
SLIDE 4

Perl in Scheme: A DSL KW.PM 2007/10

DSL

  • Domain Specific Language
  • I’m claiming the macros and functions in this

presentation form a DSL because they provide new syntax

  • It’s a really weak DSL so far
  • Perl in Scheme

Abram Hindle 4

slide-5
SLIDE 5

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Scheme is a lisp derived programming language
  • Lexically scoped (static scope)
  • Supports Functional programming
  • Minimalist
  • Continuations
  • Tried to be similar to lambda calculus

Abram Hindle 5

slide-6
SLIDE 6

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Types and syntax

– Numbers (integers, floats, rationals, etc.) – Symbols ’this-is-a-symbol – procedures (f x) – Strings “Hi!” – chars # A (Capital A) – pair (a . b)

Abram Hindle 6

slide-7
SLIDE 7

Perl in Scheme: A DSL KW.PM 2007/10

– list (a b c) – booleans #t #f – Vector – ports

Abram Hindle 7

slide-8
SLIDE 8

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Uses s-expressions

– Prefix notation, not infix. – (function-name param1 param2 param3) – (= (+ (* 1 2) 3) 6)

Abram Hindle 8

slide-9
SLIDE 9

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • cons

– Just about everything in scheme is made up of linked lists – (cons a b) makes a cons cell of a b

∗ (a . b) ∗ (list 1 2 3) versus (cons 1 (cons 2 (cons 3)))

Abram Hindle 9

slide-10
SLIDE 10

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • car

– car gets the head of a cons

∗ (car (list 1 2 3)) is 1 ∗ (car (cons 1 ’())) is 1

Abram Hindle 10

slide-11
SLIDE 11

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • cdr

– cdr gets the tail of a cons

∗ (cdr (cons 1 2)) is 2 ∗ (cdr (cons 1 (cons 2 ’()))) is (2) or (cons 2 ’())

Abram Hindle 11

slide-12
SLIDE 12

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Composition of car and cdr

– cadr - gets the head of the tail of a cons cell

∗ (cadr (list 1 (list 2))) is 2 ∗ (cadr ’(1 (2))) is 2

Abram Hindle 12

slide-13
SLIDE 13

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Procedures

– lambda produces an anonymous function – define produces a named function – lambda can be assigned in defines and lets

Abram Hindle 13

slide-14
SLIDE 14

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Procedures

– (lambda (x) x) - identity of 1 argument – (define (identity x) x) - named function identity – (define (square x) (* x x))

Abram Hindle 14

slide-15
SLIDE 15

Perl in Scheme: A DSL KW.PM 2007/10

Scheme

  • Macros

– Functions which return lists of symbols which look like scheme code that become scheme code – Get around problems that simple function calls cannot

Abram Hindle 15

slide-16
SLIDE 16

Perl in Scheme: A DSL KW.PM 2007/10

Chicken

  • We’ll be using chicken scheme
  • By Felix L. Winkelmann
  • http://callcc.org/

Abram Hindle 16

slide-17
SLIDE 17

Perl in Scheme: A DSL KW.PM 2007/10

Making Scheme Useful

  • Scheme is tiny

– R5RS is less than 60 pages

( require−extension posix ) ( require−extension srfi−1 ) ; ; l i s t s @@ ( require−extension srfi−13 ) ; ; s t r i n g s @@ Abram Hindle 17

slide-18
SLIDE 18

Perl in Scheme: A DSL KW.PM 2007/10

Slurpfile

  • ( define

( slurp−file f i l e ) ( with−input−from−file f i l e read−all−lines ) ) Abram Hindle 18

slide-19
SLIDE 19

Perl in Scheme: A DSL KW.PM 2007/10

Perl ENV

  • ( define

(ENV x ) ( cdr ( assoc x ( current−environment ) ) ) ) ) Abram Hindle 19

slide-20
SLIDE 20

Perl in Scheme: A DSL KW.PM 2007/10

Perl pop

  • Note we’re using a macro

( define−macro pop ! ( lambda ( x ) ‘ ( i f ( null? , x ) # f ( l e t ( ( r ( reverse , x ) ) ) ( l e t ( ( k ( car r ) ) ) ( set ! , x ( reverse ( cdr r ) ) ) k ) ) ) ) ) Abram Hindle 20

slide-21
SLIDE 21

Perl in Scheme: A DSL KW.PM 2007/10

Perl push

  • Note we’re using a macro

( define−macro push ! ( lambda ( x y ) ‘ ( set ! , x ( reverse (cons , y ( reverse , x ) ) ) ) ) ) Abram Hindle 21

slide-22
SLIDE 22

Perl in Scheme: A DSL KW.PM 2007/10

Perl unshift!

  • Note we’re using a macro

( define−macro u n s h i f t ! ( lambda ( x y ) ‘ ( set ! , x (cons , y , x ) ) ) ) Abram Hindle 22

slide-23
SLIDE 23

Perl in Scheme: A DSL KW.PM 2007/10

Perl shift!

  • Note we’re using a macro

( define−macro s h i f t ! ( lambda ( x ) ‘ ( i f ( null? , x ) # f ( l e t ( ( k ( car , x ) ) ) ( set ! , x ( cdr , x ) ) k ) ) ) ) Abram Hindle 23

slide-24
SLIDE 24

Perl in Scheme: A DSL KW.PM 2007/10

Perl ARGV

  • ( define

( perl−argv) ( l e t ( ( args ( argv ) ) ) ( i f (and ( p a i r ? args ) ( string=? ” csi ” ( pathname−file ( car args ) ) ) ) ( cddr args ) ( cdr args ) ) ) ) Abram Hindle 24

slide-25
SLIDE 25

Perl in Scheme: A DSL KW.PM 2007/10

Perl my

  • ( define−macro begin−my

( l e t ( ( ismy? ( lambda ( x ) (and ( p a i r? x ) ( eqv? ’my ( car x ) ) ) ) ) ) ( lambda x ( l e t loop ( ( l x ) ) ( i f ( p a i r ? l ) ( l e t ( ( head ( car l ) ) ) ( i f ( ismy? head) ( l i s t ’ l e t ( l i s t ( l i s t ( cadr head) ( caddr head ) ) ) ( loop ( cdr l ) ) ) ( i f ( p a i r? ( cdr l ) ) ( l i s t ’ begin ( car l ) ( loop ( cdr l ) ) ) ( l i s t ’ begin ( car l ) ) ) ) ) ) ) ) ) ) Abram Hindle 25

slide-26
SLIDE 26

Perl in Scheme: A DSL KW.PM 2007/10

Perl my

  • Here’s a test case

( define (begin−my−test) (begin−my (my a 99) (my b 2) ( set ! a (+ a b ) ) ; 103 ( print a ) ( set ! a (+ a b ) ) ; 105 ( print a ) (my c 3) (my a (+ a c ) ) ( print a ) a ) ) Abram Hindle 26

slide-27
SLIDE 27

Perl in Scheme: A DSL KW.PM 2007/10

But what about hashes!

  • Most schemes have a hash implementation, R6RS

has one – R5RS doesn’t

  • SRFI-69
  • The hash functions are very wordy
  • We’ll need this code
  • Perl’s auto vivification can cause us problems

( define (hash−cons−key hash−table key value ) Abram Hindle 27

slide-28
SLIDE 28

Perl in Scheme: A DSL KW.PM 2007/10 (hash−table−update ! / d e fa u l t hash−table key ( lambda ( x ) (cons value x ) ) ’ ( ) ) ) Abram Hindle 28

slide-29
SLIDE 29

Perl in Scheme: A DSL KW.PM 2007/10

A single hashtable

  • ( define

(make−easy−hash) ( l e t∗ ( ( h (make−hash−table ) ) ( acc ( lambda ( x . y ) ( case x ( ’ get (hash−table−ref h ( car y ) ) ) ( ’ set (hash−table−set! h ( car y ) ( cadr y ) ) ) ( ’ has ( hash−table−exists? h ( car y ) ) ) ( ’ del ( hash−table−delete! h ( car y ) ) ) ( ’ cons (hash−cons−key h ( car y ) ( cadr y ) ) ) ( ’ a l i s t (hash−table−

>a l i s t

h ) ) ( else ( error ( l i s t ”Don ’ t know what t h i s i s : ” x ) ) ) ) ) ) ) acc ) ) Abram Hindle 29

slide-30
SLIDE 30

Perl in Scheme: A DSL KW.PM 2007/10

A single hashtable

  • We can use it like so:

( l e t ( ( h (make−easy−hash ) ) ) ( h ’ set ” l o l ” ” hy ” ) ( print ( h ’ has ” l o l ” ) ) ( print ( h ’ get ” l o l ” ) ) ( h ’ del ” l o l ” ) ( print ( h ’ has ” l o l ” ) ) ) Abram Hindle 30

slide-31
SLIDE 31

Perl in Scheme: A DSL KW.PM 2007/10

What about nested hash tables?

  • Well lets just hack it and pretend we did it

( define (make−easy−n−key−hash) ( define (mk−key keys ) keys ) ( define (get−key y ) (mk−key ( car y ) ) ) ( define (get−arg y ) ( cadr y ) ) ( define (get−arg−no−key y ) ( car y ) ) ( l e t∗ ( ( h (make−hash−table equal ? )) ( acc ( lambda ( x . y ) ( case x ( ’ get (hash−table−ref h (get−key y ) ) ) ( ’ set (hash−table−set! h (get−key y ) (get−arg y ) ) ) ( ’ has ( hash−table−exists? h (get−key y ) ) ) Abram Hindle 31

slide-32
SLIDE 32

Perl in Scheme: A DSL KW.PM 2007/10 ( ’ del ( hash−table−delete! h (get−key y ) ) ) ( ’ cons (hash−cons−key h (get−key y ) (get−arg y ) ) ) ( ’ a l i s t (hash−table−

>a l i s t

h ) ) ( ’get−nth−keys ( delete−duplicates ! ( else ( error ( l i s t ”Don ’ t know what t h i s i s : ” x ) ) ) ) ) ) ) acc ) ) Abram Hindle 32

slide-33
SLIDE 33

Perl in Scheme: A DSL KW.PM 2007/10

What about nested hash tables?

  • How do we use them?

( define (test−easy−n−hash) ( define h (make−easy−n−key−hash) ) ( h ’ set ’ ( ” abram” ” loves ” ) ” l i x i n ” ) ( h ’ set ’ ( ” abram” ” hates ” ) ” work ” ) ( h ’ set ’ ( ” l i x i n ” ” loves ” ) ” abram” ) ( l i s t ( h ’ get ’ ( ” abram” ” loves ” ) ) ( h ’ get ’ ( ” l i x i n ” ” loves ” ) ) ( h ’ get ’ ( ” abram” ” hates ” ) ) ) ) (test−easy−n−hash) Abram Hindle 33

slide-34
SLIDE 34

Perl in Scheme: A DSL KW.PM 2007/10

Convienance

  • ( define eq string =?)

( define ne ( lambda ( x y ) ( not (eq x y ) ) ) ) ( define eq string =?) ( define ne ( lambda ( x y ) ( not (eq x y ) ) ) ) ( define ( subst from to s t r ) ( string−substitute from to s t r ) ) ( define unlink delete−file∗) ( define l i n k file−link ) Abram Hindle 34

slide-35
SLIDE 35

Perl in Scheme: A DSL KW.PM 2007/10

Perl while(<>)

  • ( define

(read−lines−from−

< > f i l e l i s t

f ) ( define ( handle−file f i l e ) ( lambda ( filename ) ( with−input−from−file filename ( lambda ( ) (handle−each−line f ) ) ) ) ) ( define ( handle−stdin ) (handle−each−line f ) ) (cond ( ( p a i r ? f i l e l i s t ) (for−each handle−file f i l e l i s t ) ) ( ( or (and ( string? f i l e l i s t ) (eq f i l e l i s t ”

” ) ) ( l i s t ? f i l e l i s t ) ) ( handle−stdin ) ) ( ( and ( string? f i l e l i s t ) ) ( handle−file f i l e l i s t ) ) ( else ( error ( l i s t ”What i s ” f i l e l i s t ) ) ) ) ) Abram Hindle 35

slide-36
SLIDE 36

Perl in Scheme: A DSL KW.PM 2007/10

Conclusions

  • Tiny DSL of perl

– Taking some perl features and reimplementing them – Making functions so it is easy to follow the perl way – Barely scratched the surface – sometimes it is useful to program the perl way

Abram Hindle 36

slide-37
SLIDE 37

Perl in Scheme: A DSL KW.PM 2007/10

Future Work

  • Integrate Regular Expressions better

– Chicken has regular expressions but there are add-ons for good syntax

  • maybe a perl-¿scheme convertor, or a true perl DSL
  • Handle symbols properly, handle namespaces
  • HEREDOC syntax?
  • Maybe more useful would be actually loading up perl

and making an interface such that perl libraries could

Abram Hindle 37

slide-38
SLIDE 38

Perl in Scheme: A DSL KW.PM 2007/10

be called.

Abram Hindle 38

slide-39
SLIDE 39

Perl in Scheme: A DSL KW.PM 2007/10

Reading

  • http://practical-scheme.net/wiliki/schemexref.cgi
  • http://www.schemers.org/Documents/Standards/R5RS/HTML/
  • http://srfi.schemers.org/srfi-1/srfi-1.html
  • http://srfi.schemers.org/srfi-13/srfi-13.html
  • http://callcc.org
  • http://chicken.wiki.br/Unit%20regex

Abram Hindle 39

slide-40
SLIDE 40

Perl in Scheme: A DSL KW.PM 2007/10

Thank you

  • Any Questions?

Abram Hindle 40