John Smith
John Smith

Reputation: 897

Why do I get "application: not a procedure" with this for loop in Racket?

The following code reads a csv file and based on its content generates a Prolog program:

#!/usr/bin/env racket
#lang racket/base

(define (overwrite-s-to-f fname s); Will create fname and write overwriting the previous content. 
  (with-output-to-file #:exists 'truncate fname (lambda () (displayln s))))

(define (c-o-a-line-to-f fname s); Will append a string to fname or create it if does not exist. Appends a new line.
  (with-output-to-file #:exists 'append fname (lambda () (displayln s))));


(define fname "women.csv")
(define pl-fname "females-by-Racket.pl") 
(require racket/file)
(define content (file->lines fname))
(define disc-line (string-append ":-discontiguous(" (string-replace (car content) "Name," "") ").\n"))
(overwrite-s-to-f pl-fname disc-line)
(define list-of-verbs (string-split (string-replace (car content) "Name," "") ","))

(require racket/string racket/system)


(for ((row content));content is a list of strings
  (let ((list-of-cs (string-split row ",")))
    (when (equal? (car (cdr list-of-cs)) "+")
      (displayln row)(let ((cmd (string-append "awesome("(car list-of-cs)").")))(c-o-a-line-to-f pl-fname cmd)(displayln cmd)))
    (when (equal? (car (cdr (cdr list-of-cs))) "+")(displayln row)(let ((cmd (string-append "and_intelligent("(car list-of-cs)").")))
      (c-o-a-line-to-f pl-fname cmd)(displayln cmd))))); TODO: when for each columns 2-last of women.csv

The content of women.csv:

Name,awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts
adriana_chechik,+,,,+,?,+,+,,-,,,,,
alysa_gap,+,,,,?,+,+,,-,,,,,
anna_de_ville,+,,,,,+,+,,+,-,+,-,-,
aurora_jolie,+,+,,,,,,,+,+,+,,+,
autumn_falls,,,,,,,,,+,+,-,+,+,
casey_calvert,+,,,,,,,,+,+,+,,,
dahlia_sky,+,,,,,,+,,,,,,,
dominica_lito,+,,,,,,+,,,,,,,
ella_knox,,,,,,,,,+,+,+,,+,
isabella_clark,+,,,,,,+,,,,,,,
jade_kush,,,,,,,,,+,+,,,+,
juelz_ventura,+,,,,,+,,,-,-,,,-,+
kapri_styles,,,,,,,,,+,,+,,,
kristina_milan,,,,,,,,,+,+,,,+,
kylie_sinner,+,+,,,,,,,+,,,,-,
leigh_raven,+,,,,,+,,,+,+,,,,
maserati,,,,,,,,,+,+,,,+,
miosotis,,,,,,,,,+,+,,,+,
scarlett_bloom,,,,,,,,,+,+,+,,-,
sheena_shaw,,,,,,,,,-,,+,,-,
sofia_rose,,,,,,,,,+,,,,+,
teanna_trump,+,,,,,,,,+,,+,,,
veronica_avluv,+,,,,,,+,,,,,,,
yudi_pineda,+,,,,,,,,+,+,,,,

females-by-Racket.pl is to look like so:

:-discontiguous(awesome,and_intelligent,performed_once,extreme1,extreme2,extreme3,extreme4,donkey_thing,dark_eyes,pigmented_face,pigmented_genitals,bleached,had_no_surgeries,has_augmented_breasts).

awesome(adriana_chechik).
awesome(alysa_gap).
awesome(anna_de_ville).
awesome(aurora_jolie).
and_intelligent(aurora_jolie).
awesome(casey_calvert).
awesome(dahlia_sky).
awesome(dominica_lito).
awesome(isabella_clark).
awesome(juelz_ventura).
awesome(kylie_sinner).
and_intelligent(kylie_sinner).
awesome(leigh_raven).
awesome(teanna_trump).
awesome(veronica_avluv).
awesome(yudi_pineda).

but with more predicates (up to n-1 for each woman where n is the number of columns in women.csv)

The names of the columns or the numbers thereof in women.csv are likely to be frequently changed. That is partly why I wish to avoid manually coding for every when. The other concerns are the sheer amount of the lines to code (15 whens for each column) and the risk of error/typo. Is it doable to loop through every cell in list-of-cs in such way that it is taken from list-of-verbs? I've tried this but to no avail (the comment show the error message that I got):

(for ((row content))
  (let ((list-of-cs (cdr (string-split row ","))))
    (for ((cell list-of-cs))
     ; application: not a procedure; expected a procedure 
     ; that can be applied to arguments
     (set! list-of-verbs (cdr (list-of-verbs)))
     (let ((verb (car list-of-verbs))) 
       (when (equal? cell "+")
         (displayln row)
         (let ((cmd (string-append verb "(" (car row) ").")))
           (c-o-a-line-to-f pl-fname cmd)))
       ))))

Upvotes: 0

Views: 106

Answers (1)

mnemenaut
mnemenaut

Reputation: 820

named let is a useful form to be familiar with:

#lang scheme

(define (csv->attributes rows) ;; ListOfString -> ListOfString
  ;; produce "column-header(row-name)" for "+" entries in csv (see example)
  (let ([fields (string-split (car rows) ",")])
    (let next-row ([rows (cdr rows)] [result (list)])
      (cond
        [(null? rows) (reverse result) ]
        [else
         (let* ([cells (string-split (car rows) ",")]
                [name  (car cells)])
           (let next-cell ([cells (cdr cells)] [fields (cdr fields)] [result result])
             (cond
               [(null? cells) (next-row (cdr rows) result) ]
               [else (next-cell
                      (cdr cells) (cdr fields)
                      (if (string=? (car cells) "+")
                          (cons (string-append (car fields) "(" name ")") result)
                          result)) ]))) ]))))

(define trio '("Name,fast,slow,sidles"
               "Achilles,+,,"
               "Tortoise,,+,"
               "Crab,,+,+"))
Welcome to DrRacket, version 8.5 [cs].
Language: scheme, with debugging.
> (csv->attributes trio)
("fast(Achilles)" "slow(Tortoise)" "slow(Crab)" "sidles(Crab)")
> 

Upvotes: 1

Related Questions