www.delorie.com/archives/browse.cgi   search  
Mail Archives: geda-user/2015/07/16/08:27:27

X-Authentication-Warning: delorie.com: mail set sender to geda-user-bounces using -f
X-Recipient: geda-user AT delorie DOT com
X-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20120113;
h=date:from:to:subject:message-id:mail-followup-to:references
:mime-version:content-type:content-disposition:in-reply-to
:user-agent;
bh=3fbmmmg4xVgLg+AY2sp2f+GAxupHjZdZFGUDXp37SMY=;
b=QzCAdu4oc3Kfx2a2jx0QuqzZqAikbkSgOQxbqooCL6Gv80VaIprA9sqksyF6OIz0ta
l7jlGnmA97cpPCQsOkX4nHBHEiELhVboO0uubjndTSaJ1CaNMojYhUE2YA9ncII0Ob11
scv0/f4HUuDzW8nUNvHfhjqiaHJulUzf0TGqvdXASU/p3PQ3buXD9TLPRQ2E0HCsk6t0
PFBQa2if6oB2kVbQPJYt3dJCI5UMB20o5gIroRLO4j+VkDKGSLqJ0MHZ1g88H5Nn1F9E
eSkVpNIWDu0WNznJc7O8b1HoBvzD1Htcl5Rkz4oslDLVYQGiGwNpH2P6d1DrAuc4BL5D
nRBQ==
X-Received: by 10.112.13.97 with SMTP id g1mr9174025lbc.52.1437049631389;
Thu, 16 Jul 2015 05:27:11 -0700 (PDT)
Date: Thu, 16 Jul 2015 15:27:08 +0300
From: "Vladimir Zhbanov (vzhbanov AT gmail DOT com) [via geda-user AT delorie DOT com]" <geda-user AT delorie DOT com>
To: geda-user <geda-user AT delorie DOT com>
Subject: Re: [geda-user] Re: developer excitement?
Message-ID: <20150716122708.GA16740@localhost.localdomain>
Mail-Followup-To: geda-user <geda-user AT delorie DOT com>
References: <201507092128 DOT t69LSc2j001777 AT envy DOT delorie DOT com>
<CAM2RGhQUmZ9Wz9gWNtGs22gRD-zFwq6504rcfhWBSNYft+9MPw AT mail DOT gmail DOT com>
<CAM2RGhQNdDJH6NRDOF1mEY6kxajRBESwr5HZ7eRJ0UpJfA5=Dw AT mail DOT gmail DOT com>
<201507120012 DOT t6C0CfnW014811 AT envy DOT delorie DOT com>
<CAM2RGhSM+iSS8Ysw+esVM=AGsWL=L3KMgKCjw+Ham_nYQ0pUWA AT mail DOT gmail DOT com>
<CAM2RGhSHaBjVM1D_6ZX_A4DeMuAo01X6BXpgzJnxq9w+CGfC9A AT mail DOT gmail DOT com>
<201507120145 DOT t6C1jnc8020051 AT envy DOT delorie DOT com>
<1436950214 DOT 2876 DOT 57 DOT camel AT linetec>
<20150715202828 DOT GA17392 AT localhost DOT localdomain>
<CAHUm0tPBRLypTYd8uTEM-bNON1vF3aHiNNyyjYvVhyjH4a8zyg AT mail DOT gmail DOT com>
MIME-Version: 1.0
In-Reply-To: <CAHUm0tPBRLypTYd8uTEM-bNON1vF3aHiNNyyjYvVhyjH4a8zyg@mail.gmail.com>
User-Agent: Mutt/1.5.23 (2014-03-12)
Reply-To: geda-user AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: geda-user AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Thu, Jul 16, 2015 at 09:09:36AM +0930, Erich Heinzle (a1039181 AT gmail DOT com) [via geda-user AT delorie DOT com] wrote:
...
> So, please do go into further detail, it would be of interest to me and to
> others I am sure.
OK, let's go step by step.  The steps will be small as I don't
have much time and every day shrinks its amount.

Let's start with hooks.

What is a hook?

A hook is when your wife catches your hand which is trying to
reach mug with beer.
Or it is when you tried to shout at a boxer and he hooked you at
that moment (you wasn't waiting, huh?).

So, a hook is an action someone wants to carry out at the time some
specific event is taking place. In the context of a programming
language, the exact contents of the action has to be given in the
form of a function/procedure, and the event has to be specified as
a place in your program where you want to call this function.

How to define a hook in Guile? It's easy:
  (make-hook number-of-arguments)

Run 'guile' and type at the command prompt:
  (make-hook 2)
-| $1 = #<hook 2 8ea9238>


The '-|' symbols here mean the output of guile.
Every time you type this you'll see different addresses (such as
8ea9238 here) because every time a new hook is made. Do you need
them as much? I think no. Below we'll define our own hook and make
it useful.

Type
  (define my-lovely-hook (make-hook))

The (define ...) call just adds the name for the procedure.
Every time you type 'my-lovely-hook' at the prompt the
result is the same procedure you've assigned with the given name.
(In Scheme you can assign and reassign procedures as easy as
variables, you'll see this in the code below.) As for 'make-hook',
you see it has no arguments, this is because some Scheme
procedures may take indefinite or various number of arguments. In
this case, let's look through the guile info manual ('info guile')
and search for 'make-hook' there.  You'll learn that the procedure
argument is optional and defaults to zero if omitted.

Now, let's consider the hook of the boxer given above. Imagine
that you are able to clone yourself and don't want to get red as
the boxer's hook reaches your nose, so you issue a clone in the
front of you, who gets the hook.

So you know the needed moment and let's suppose you have prepared
your own hook for this case using Scheme. Let's call it
'make-clone-to-get-red-hook' and let it is invoked when the
boxer-mauley-reaches-my-nose-hook hook is in action. We need also
to know when the boxer begins his strike to issue a clone in time.
Let's name that event 'the-angry-boxer-hook'. So your strategy
would be the following:
  as you see the boxer wants to strike us, we issue the clone and
    as this makes us furious we turn green
  as we see our nose has been smashed, we cheat and make our clone
    get red to show he has got the strike, not we :p


Replace yourself with selected objects and your clone with the
objects that will be inserted and you'll get how it works.

OK, now the code with comments. I hope it may clear and demonstrate some
of the moments above. (Warning: the code is working, you can copy-paste
it into your ~/.gEDA/gschemrc to see how it works).


----------------------8<----------------------

; For doing our work we need some magic means:
; the magic wand
(use-modules (geda page))
; the magic paint
(use-modules (gschem selection))
; the magic hook
(use-modules (gschem hook))
; The 'use-modules' plugs in the named module with a predefined
; function set

; Let's suppose then that I am a procedure returning selected
; object(s) on the active page. The 'page-selection' and
; 'active-page' procedures are described in the geda-scheme info
; page.
(define (me) 
  (page-selection (active-page)))

; The magic here in that you can save existing procedures
; with other names and redefine them later, if you want
(define the-angry-boxer-hook copy-objects-hook)
(define boxer-mauley-reaches-my-nose-hook paste-objects-hook)
; What's this? Try to guess.
(define scream display)

; The next two calls are equivalent where the second one is just
; abbreviation of the first. See a short description of lambda below

; Apply magic paint
(define make-him-turn-green!
  (lambda (they)
    (for-each deselect-object! they)))
; If I was always a single entity I would use just the following
; form:
; (define make-him-turn-green! deselect-object!)
; However, I am a crowd, that is why I have to use 'for-each' here.

; Apply magic paint of another color
(define (make-him-get-red! they)
  (for-each select-object! they))

; Now the magic begins...
; Let's define clone to be an empty list because it doesn't exist yet
(define clone '())

; Call my clone
(define (call-my-clone-for-help)
  ; He's here: "Your majesty? Yes, sir."
  clone)

(define (issue-clone! a-hysterical-subject)
  (set! clone a-hysterical-subject))

; Let's prepare a hook for my clone
(define make-clone-to-get-red-hook (make-hook))

; (add-hook! hook-name procedure) hangs one more procedure on the
; named hook. We can add them as many times as we want.
(add-hook! make-clone-to-get-red-hook
  ; 'lambda (args)' is like 'type function-name (args)' in C
  ; though without name; we can add a name using
  ; (define function-name (lambda (args) ...))
  ; But why should we bother to add any name if it is used once in
  ; the code?
  ; Another difference is that lambda always has the same type,
  ; it's a procedure :) That's all.
  (lambda ()
    (make-him-get-red! (call-my-clone-for-help))  ; call my clone and kick him
                                                  ; as he is smiling looking at me
  ))

; How to make clone is another story, I'am not going to tell you
; about this yet. At least, you have to have a magic wand... 
; (Seriously, gschem gives the list of copied objects to the hook;
; didn't you forget that the-angry-boxer-hook is really the same
; as copy-objects-hook? This is defined somewhere deep in the
; gschem code. Read 'info geda-scheme' if you want to know what
; arguments gschem hooks like to eat)
(add-hook! the-angry-boxer-hook
  (lambda (somebody)
    ; somebody is a substance (the copied object list) we called.
    ; It is a result of a wave of our magic wand. We'll make him
    ; our clone soon.
    (begin  ; begin is just to put our actions in order
      (scream "I don't fear you at all!\n")
      (make-him-turn-green! (me)) ; yes, it's me, and I want to turn green
      (issue-clone! somebody)     ; here we turn the substance into our clone
                                  ; and wait until the next event will happen
      )))

; Now, the next event we have been waiting
(add-hook! boxer-mauley-reaches-my-nose-hook
  (lambda (somebody)
    (scream "Oh, my nose...\n")
    (run-hook make-clone-to-get-red-hook) ; poor clone!
                                          ; I believe the boxer didn't notice
                                          ; that I'm already green
    ; (run-hook hook-name) executes all procedures hanged on the
    ; named hook at once
    ))

---------------------->8----------------------

That's all, folks... (yet)

Any comments, questions, opinions?

Cheers,
  Vladimir

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019