Toon posts:

[SCHEME] for macro

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hey, ben bezig in scheme om een for-macro te maken.
Het volgende heb ik:

code:
1
2
3
4
5
6
(define-macro for
  (lambda (from to . branch)
    (unless (> from to)
      (list 'begin branch))))

(for 1 10 (display "Hello world from 1 to 10")(newline))


Nou verwacht ik dat 10x "Hello world from 1 to 10" afgedrukt wordt,
helaas is dat dus niet het geval..
Wat doe ik verkeerd, zo ver kan ik er niet naast zitten, of wel?


Het resultaat is overigens dat 1 maal "Hello wordl from 1 to 10" afgedrukt
wordt gevolgd door deze error:

procedure application: expected procedure, given: #<void>; arguments were: #<void>
edit:
Resultaat + error toegevoegd.

[ Voor 32% gewijzigd door Verwijderd op 12-04-2004 17:27 ]


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Als je macro's in Scheme wilt schrijven, moet je gebruik maken van quoting, back-quoting en quasi-quoting.

Misschien kan dit documentje je aardig op weg helpen :)

Welke implementatie van Scheme gebruik je ? drScheme, MacScheme , ...
Ik zie ook dat je 'unless' gebruikt. Dit is geen standaard special-form in Scheme.

[ Voor 24% gewijzigd door whoami op 12-04-2004 18:19 ]

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Topicstarter
Thxie! Heb na mn post nog verder zitten werken en kwam tot het volgende:

code:
1
2
3
4
5
6
7
8
9
(define-macro for
  (lambda (begin end stap . branch)
    (let loop ((i begin))
      (when ( < i end )
        `(begin
          (list 'begin ,@branch)
          (+ i stap))))))

(for 1 10 1 (display "Hello world from 1 to 10")(newline))


Resultaat is 1x "Hello world from 1 to 10"
plus een error: reference to undefined identifier: i

Als ik dan (+ i stap) weg laat, zou die oneindig moeten doorgaan.
Toch print ie 1x "Hello world from 1 to 10" plus: (begin #<void> #<void>)

Nu eerst ff je docje doorspitten :P
Btw, ik gebruik Dr Scheme (language: Pretty Big).

Verwijderd

Topicstarter
Gewijzigd tot:

code:
1
2
3
4
5
6
(define-macro for
  (lambda (start end stap . branch)
    (when ( < start end )
      `(list 'begin ,@branch))))

(for 1 10 1 (display "Hello world from 1 to 10")(newline))


Output: 1x "Hello world from 1 to 10"
met: (begin #<void> #<void>)

  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
Waarom zou je 'begin' in je macro gebruiken. Is het niet beter uw 'branch' gewoon als 1 expressie te laten interpreteren. Wanneer de gebruiker van uw macro dan toch meerdere expressie in de FOR wil zetten, moet hij er maar zelf
code:
1
(begin ... )

rondzetten.
Ik denk dat dit al wat eenvoudiger zal zijn.

En dan nog iets :
Ik ben wel niet erg vertrouwd met macro's in Scheme, maar je moet toch ook nog ergens je 'from' verhogen enzo ...

[ Voor 23% gewijzigd door whoami op 12-04-2004 18:55 ]

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


Verwijderd

Topicstarter
Feyd-Rautha schreef op 12 april 2004 @ 18:54:
Waarom zou je 'begin' in je macro gebruiken. Is het niet beter uw 'branch' gewoon als 1 expressie te laten interpreteren. Wanneer de gebruiker van uw macro dan toch meerdere expressie in de FOR wil zetten, moet hij er maar zelf
code:
1
(begin ... )

rondzetten.
Ik denk dat dit al wat eenvoudiger zal zijn.

En dan nog iets :
Ik ben wel niet erg vertrouwd met macro's in Scheme, maar je moet toch ook nog ergens je 'from' verhogen enzo ...
Ik was inderdaad bewust dat die macro oneindig moest zijn. Waarom ik de begin erin laat staan is inderdaad om meerdere expressies tegelijk uit te voeren.

Inmiddels ben ik gekomen tot dit:

Waarschuwing: dit is een oneindige loop!
code:
1
2
3
4
5
(define-macro for
  (lambda (start eind stap . branch)
   `(do ()
      ((not ,(< start eind)) #t)
        ,@branch)))


Thanks to: Feyd-Rautha
Nu moet ik alleen nog even uitvissen waar ik iets als (+ start stap) doe :D

Verwijderd

een heel erg algemene oplossing is denk de volgende
code:
1
2
3
4
5
(define-macro for
  (lambda (variabele from to . branch)
    `(do ((,variabele ,from (+ ,variabele 1)))
       ((> ,variabele ,to))
       ,@branch)))


het kan ook zonder dat men een variabele moet opgeven, hetgeen mss wel veel handiger is, is om "define-syntax" te gebruiken dan, die heeft dacht ik een aantal voordelen (bv dat er geen verwarring kan ontstaan tussen de verschillende variabelen

[ Voor 2% gewijzigd door Verwijderd op 12-04-2004 19:07 . Reden: blijkbaar toch iets te laat ]


Verwijderd

Topicstarter
Verwijderd schreef op 12 april 2004 @ 19:06:
een heel erg algemene oplossing is denk de volgende
code:
1
2
3
4
5
(define-macro for
  (lambda (variabele from to . branch)
    `(do ((,variabele ,from (+ ,variabele 1)))
       ((> ,variabele ,to))
       ,@branch)))


het kan ook zonder dat men een variabele moet opgeven, hetgeen mss wel veel handiger is, is om "define-syntax" te gebruiken dan, die heeft dacht ik een aantal voordelen (bv dat er geen verwarring kan ontstaan tussen de verschillende variabelen
Leek veelbelovend, helaas krijg ik n error:
named let: bad syntax (name not an identifier) in: 1

Kan ook aan Dr Scheme liggen :P

Hoewel deze ook erg veel op mijn net iets eerder geposte macro lijkt.. |:(

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik ben absoluut (nog) niet goed bekend met Scheme macros, maar waarom gebruik je geen define-syntax (R5RS macros)? Dat wordt over het algemeen gezien als de 'nieuwe' manier van macros, omdat ze standaard al hygienic zijn.

Ik heb even wat zitten proberen en kwam op dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
(define-syntax myfor
   (syntax-rules ()
     ((myfor from to code)
      (unless (> from to) 
        code
        (eval `(myfor (+ from 1) to code))))))

(begin
  (myfor 1 10
    (begin
      (display "Hey")
      (newline)))
  (exit))

Ik vond de eval ` niet zo mooi, maar kon er niet uitkomen of dat ook anders/mooier kon. Ik zit zelf nog in het hello world stadium, dus er zitten misschien wel verschrikkelijke dingen in ;) . Ik gebruik MzScheme.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment

Pagina: 1