unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Guile 100 #6: CGI and MySQL
@ 2013-05-01 17:17 Mike Gran
  2013-05-02  3:10 ` Nala Ginrut
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Mike Gran @ 2013-05-01 17:17 UTC (permalink / raw)
  To: Guile User

Challenge #6 in the Guile 100 Programs Project is to write a Guile
CGI script that accesses a MySQL-family database.   It is the second
challenge in this month's theme, which is "Web 1.0 --
Web 1990s style".

Problem: http://www.lonelycactus.com/guile100/html/Problem-6.html

The Guile 100 Programs Project is an attempt to collaboratively
generate a set of examples of how to use the GNU Guile implementation
of Scheme.

There is a 100 USD bounty for writing a readable solution to problems.

Also, I'm changing up the rules.  I had made it pretty complicated
to contribute, I suppose, because I don't really want to create
competition for fear of alienating anyone.  But, the barrier to entry
was too high, perhaps?  So anyone can fork the repo and tell me to
pull it or just send me a solution by e-mail at
guile100 [at] lonelycactus.com

Three other problems remain incomplete, so feel free to try your
hand at one of them as well.

    - Challenge #5: PHP-style Guile
    - Challenge #4: TAR File Archives
    - Challenge #3: LZW Compression

If the backlog reaches six open problems, I guess I'll declare the
project DOA.

Thanks,

Mike Gran



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-01 17:17 Guile 100 #6: CGI and MySQL Mike Gran
@ 2013-05-02  3:10 ` Nala Ginrut
  2013-05-03  3:26 ` Daniel Hartwig
  2013-05-03 23:11 ` Ian Price
  2 siblings, 0 replies; 8+ messages in thread
From: Nala Ginrut @ 2013-05-02  3:10 UTC (permalink / raw)
  To: Mike Gran; +Cc: Guile User

On Wed, 2013-05-01 at 10:17 -0700, Mike Gran wrote:
> Challenge #6 in the Guile 100 Programs Project is to write a Guile
> CGI script that accesses a MySQL-family database.   It is the second
> challenge in this month's theme, which is "Web 1.0 --
> Web 1990s style".
> 

Since we have mysql in guile-dbi, how about a maria-db binding?

> Problem: http://www.lonelycactus.com/guile100/html/Problem-6.html
> 
> The Guile 100 Programs Project is an attempt to collaboratively
> generate a set of examples of how to use the GNU Guile implementation
> of Scheme.
> 
> There is a 100 USD bounty for writing a readable solution to problems.
> 
> Also, I'm changing up the rules.  I had made it pretty complicated
> to contribute, I suppose, because I don't really want to create
> competition for fear of alienating anyone.  But, the barrier to entry
> was too high, perhaps?  So anyone can fork the repo and tell me to
> pull it or just send me a solution by e-mail at
> guile100 [at] lonelycactus.com
> 
> Three other problems remain incomplete, so feel free to try your
> hand at one of them as well.
> 
>     - Challenge #5: PHP-style Guile
>     - Challenge #4: TAR File Archives
>     - Challenge #3: LZW Compression
> 

I wish some guys could take up these interesting work, and these work
will definite be used in Artanis. If there're really no guys want to
try, I'll do it for myself. 
Anyway, it's a challenge and practice for guilers, don't miss it. ;-) 

> If the backlog reaches six open problems, I guess I'll declare the
> project DOA.
> 
> Thanks,
> 
> Mike Gran
> 





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-01 17:17 Guile 100 #6: CGI and MySQL Mike Gran
  2013-05-02  3:10 ` Nala Ginrut
@ 2013-05-03  3:26 ` Daniel Hartwig
  2013-05-03 23:11 ` Ian Price
  2 siblings, 0 replies; 8+ messages in thread
From: Daniel Hartwig @ 2013-05-03  3:26 UTC (permalink / raw)
  To: Mike Gran; +Cc: Guile User

[-- Attachment #1: Type: text/plain, Size: 1039 bytes --]

On 2 May 2013 01:17, Mike Gran <spk121@yahoo.com> wrote:
> Three other problems remain incomplete, so feel free to try your
> hand at one of them as well.
>

>     - Challenge #3: LZW Compression
>

Just for fun I made a rough start at this one when you announced it.
The outer procedures are as specified in the project details, the
inner procedures operate on “streams” of any kind of data similar to
the templates in Nelsons writeup.

The universe of symbols (uncompress data) is not required to be 8 bit
integers, but it must be known in advance.

If this seems an interesting start, I'll tidy it up for pedagogy,
produce the two scripts, and of course the obligatory writeup.  The
level of abstraction in the inner procedures is perhaps a nice
opportunity to briefly compare Guiles options for processing streams
of data (i.e. containers, ports, srfi-41, input–output procedures) and
reasons for my particularly choice here.  I assumed procedures would
be less overhead than streams, but did not test it.

[-- Attachment #2: lzw.scm --]
[-- Type: application/octet-stream, Size: 3994 bytes --]

(define-module (lzw)
  #:use-module (rnrs bytevectors)
  #:use-module (rnrs io ports)
  #:use-module (srfi srfi-1)
  #:use-module (srfi srfi-26)
  #:export (lzw-compress
            lzw-uncompress
            %lzw-compress
            %lzw-uncompress))

;; This procedure adapted from an example in the Guile Reference
;; Manual.
(define (make-serial-number-generator start end)
  (let ((current-serial-number (- start 1)))
    (lambda ()
      (and (< current-serial-number end)
           (set! current-serial-number (+ current-serial-number 1))
           current-serial-number))))

(define (%lzw-compress in out done? table-size)
  (let ((codes (make-hash-table table-size))
        (next-code (make-serial-number-generator 0 table-size))
        (universe (iota 256))
        (eof-code #f))
    ;; Populate the initial dictionary with all one-element strings
    ;; from the universe.
    (for-each (lambda (obj)
                (hash-set! codes (list obj) (next-code)))
              universe)
    (set! eof-code (next-code))
    (let loop ((cs '()))
      (let ((c (in)))
        (cond ((done? c)
               (unless (null? cs)
                 (out (hash-ref codes cs)))
               (out eof-code)
               codes)
              ((hash-ref codes (cons c cs))
               (loop (cons c cs)))
              (else
               (and=> (next-code)
                      (cut hash-set! codes (cons c cs) <>))
               (out (hash-ref codes cs))
               (loop (cons c '()))))))))

(define (put-u16 port k)
  (put-u8 port (logand k #xFF))
  (put-u8 port (logand (ash k -8) #xFF)))

(define* (lzw-compress bv #:key (table-size 65536) dictionary)
  (call-with-values
      (lambda ()
        (open-bytevector-output-port))
    (lambda (output-port get-result)
      (let ((dict (%lzw-compress (cute get-u8 (open-bytevector-input-port bv))
                                 (cute put-u16 output-port <>)
                                 eof-object?
                                 table-size)))
        (if dictionary
            (values (get-result) dict)
            (get-result))))))

(define (for-each-right proc lst)
  (let loop ((lst lst))
    (unless (null? lst)
      (loop (cdr lst))
      (proc (car lst)))))

(define (%lzw-uncompress in out done? table-size)
  (let ((strings (make-hash-table table-size))
        (next-code (make-serial-number-generator 0 table-size))
        (universe (iota 256))
        (eof-code #f))
    (for-each (lambda (obj)
                (hash-set! strings (next-code) (list obj)))
              universe)
    (set! eof-code (next-code))
    (let loop ((previous-string '()))
      (let ((code (in)))
        (unless (or (done? code)
                    (= code eof-code))
          (unless (hash-ref strings code)
            (hash-set! strings
                       code
                       (cons (last previous-string) previous-string)))
          (for-each-right out (hash-ref strings code))
          (let ((cs (hash-ref strings code)))
            (and=> (and (not (null? previous-string))
                        (next-code))
                   (cut hash-set! strings <> (cons (last cs)
                                                   previous-string)))
            (loop cs)))))))

(define (get-u16 port)
  ;; Order of evaluation is important, use 'let*'.
  (let* ((a (get-u8 port))
         (b (get-u8 port)))
    (if (any eof-object? (list a b))
        (eof-object)
        (logior a (ash b 8)))))

(define* (lzw-uncompress bv #:key (table-size 65536) dictionary)
  (call-with-values
      (lambda ()
        (open-bytevector-output-port))
    (lambda (output-port get-result)
      (let ((dict (%lzw-uncompress (cute get-u16 (open-bytevector-input-port bv))
                                   (cute put-u8 output-port <>)
                                   eof-object?
                                   table-size)))
        (if dictionary
            (values (get-result) dict)
            (get-result))))))

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-01 17:17 Guile 100 #6: CGI and MySQL Mike Gran
  2013-05-02  3:10 ` Nala Ginrut
  2013-05-03  3:26 ` Daniel Hartwig
@ 2013-05-03 23:11 ` Ian Price
  2013-05-03 23:41   ` Mike Gran
  2013-05-04  1:02   ` Daniel Hartwig
  2 siblings, 2 replies; 8+ messages in thread
From: Ian Price @ 2013-05-03 23:11 UTC (permalink / raw)
  To: Mike Gran; +Cc: Guile User

Mike Gran <spk121@yahoo.com> writes:

> Also, I'm changing up the rules.  I had made it pretty complicated
> to contribute, I suppose, because I don't really want to create
> competition for fear of alienating anyone.  But, the barrier to entry
> was too high, perhaps?  So anyone can fork the repo and tell me to
> pull it or just send me a solution by e-mail at
> guile100 [at] lonelycactus.com

This is a much better approach. I was talking with Mark Weaver on IRC
earlier, and he said you had no volunteers for TAR and so was trying his
hand at it. I had volunteered for that previously, and assumed you had
picked someone else based on the method in your original
email. Apparently not.

> Three other problems remain incomplete, so feel free to try your
> hand at one of them as well.
>
>     - Challenge #5: PHP-style Guile
I started hacking together a Jinja-style templating library before[0],
but I never released it since it's kinda less nice than just using
quasiquote/sxml in practice.

I guess I could do this for you, maybe as a warmup for [1], but I think
I'd be mortified if someone ended up using it.

0. https://gist.github.com/5514959
1. http://www.pltgames.com/competition/2013/5
-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-03 23:11 ` Ian Price
@ 2013-05-03 23:41   ` Mike Gran
  2013-05-04  0:22     ` Ian Price
  2013-05-04  1:02   ` Daniel Hartwig
  1 sibling, 1 reply; 8+ messages in thread
From: Mike Gran @ 2013-05-03 23:41 UTC (permalink / raw)
  To: Ian Price; +Cc: Guile User

> From: Ian Price <ianprice90@googlemail.com>

>I had volunteered for that previously, and assumed you had
> picked someone else based on the method in your original
> email. Apparently not.

Sorry about that.  I was working with someone on that one, but,
there was no completion.

>>      - Challenge #5: PHP-style Guile
> I started hacking together a Jinja-style templating library before[0],
> but I never released it since it's kinda less nice than just using
> quasiquote/sxml in practice.

That is true, once you've been absorbed into the Scheme continuum.
But imagine that you were someone coming in from the outside: from
PHP perhaps.

I don't want to dissuade you from doing something big, but, the
actual scope of the problem as described is quite small: make a CGI
script that (a) reads its own PATH_INFO (b) finds a template by
that name (c) sends it through eguile, and (d) returns it
to the client.

Its a bad approach in practice because there is no compilation
of the templates.

-Mike



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-03 23:41   ` Mike Gran
@ 2013-05-04  0:22     ` Ian Price
  0 siblings, 0 replies; 8+ messages in thread
From: Ian Price @ 2013-05-04  0:22 UTC (permalink / raw)
  To: Mike Gran; +Cc: Guile User

Mike Gran <spk121@yahoo.com> writes:

> I don't want to dissuade you from doing something big, but, the
> actual scope of the problem as described is quite small: make a CGI
> script that (a) reads its own PATH_INFO (b) finds a template by
> that name (c) sends it through eguile, and (d) returns it
> to the client.
I've just reread your file on this, and you are right. My brain must
have switched off while reading :)

> Its a bad approach in practice because there is no compilation
> of the templates.
Indeed

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-03 23:11 ` Ian Price
  2013-05-03 23:41   ` Mike Gran
@ 2013-05-04  1:02   ` Daniel Hartwig
  2013-05-04  1:11     ` Mike Gran
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Hartwig @ 2013-05-04  1:02 UTC (permalink / raw)
  To: Mike Gran, Guile User

On 4 May 2013 07:11, Ian Price <ianprice90@googlemail.com> wrote:
> Mike Gran <spk121@yahoo.com> writes:
>
>> Also, I'm changing up the rules.  I had made it pretty complicated
>> to contribute, I suppose, because I don't really want to create
>> competition for fear of alienating anyone.  But, the barrier to entry
>> was too high, perhaps?  So anyone can fork the repo and tell me to
>> pull it or just send me a solution by e-mail at
>> guile100 [at] lonelycactus.com
>
> This is a much better approach. I was talking with Mark Weaver on IRC
> earlier, and he said you had no volunteers for TAR and so was trying his
> hand at it. I had volunteered for that previously, and assumed you had
> picked someone else based on the method in your original
> email. Apparently not.
>

I also had assumed that a person need only volunteer once, and then is
considered for any project.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Guile 100 #6: CGI and MySQL
  2013-05-04  1:02   ` Daniel Hartwig
@ 2013-05-04  1:11     ` Mike Gran
  0 siblings, 0 replies; 8+ messages in thread
From: Mike Gran @ 2013-05-04  1:11 UTC (permalink / raw)
  To: Daniel Hartwig, Guile User

> From: Daniel Hartwig <mandyke@gmail.com>

> I also had assumed that a person need only volunteer once, and then is
> considered for any project.

I thought that too, but, I'd end up assigning people to do tasks
they may have no interest in. Apologies again.  My first time
attempting anything like this.  

-Mike




^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2013-05-04  1:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-01 17:17 Guile 100 #6: CGI and MySQL Mike Gran
2013-05-02  3:10 ` Nala Ginrut
2013-05-03  3:26 ` Daniel Hartwig
2013-05-03 23:11 ` Ian Price
2013-05-03 23:41   ` Mike Gran
2013-05-04  0:22     ` Ian Price
2013-05-04  1:02   ` Daniel Hartwig
2013-05-04  1:11     ` Mike Gran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).