Aller au contenu

Messages recommandés

Posté(e)

salut à tous,

empêtré dans la migration vers 2015, je me bas avec les command-s.

comme je veux pouvoir gérer plusieurs version et que command-s ne marche pas avec la 2012,

j'essaie plutôt de remplacer par vl-cmdf (plutôt que de devoir tester les versions)

et là j'ai cette curiosité :

 

(progn(setq lpt (pw_poly_buffer (enam) 1))
  (eval (append '(VL-CMDF "_pline") (mapcar 'quote lpt) '("_close"))))

 

qui marche très bien, sauf que tous les points sont confondus :

(setq lpt ((-4007.29 77.6245) (-3836.77 115.533) (-3831.78 114.556) (-3832.16 112.594) (-3836.75 113.49) (-4006.85 75.6722)))
(mapcar 'quote lpt) -> 
((quote (-4006.85 75.6722)) (quote (-4006.85 75.6722)) (quote (-4006.85 75.6722)) (quote (-4006.85 75.6722)) (quote (-4006.85 75.6722)) (quote (-4006.85 75.6722)))

 

Bizarre ou tout à fait logique ?

 

Gégé

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

Posté(e)

Salut,

 

C'est curieux en effet.

Je pense que c'est dû à la fonction quote.

 

J'ai toujours pensé que mapcar était implémentée un peu comme ça :

(defun map (f l)
 (if l
   (cons ((eval f) (car l)) (map f (cdr l)))
 )
)

Or ceci ne fonctionne pas avec quote (contrairement aux autres fonctions), par contre, en utilisant apply à la place de eval, ça marche :

(defun map (f l)
 (if l
   (cons (apply f (list (car l))) (map f (cdr l)))
 )
)

et l'expression :

(eval (append '(VL-CMDF "_pline") (map 'quote lpt) '("_close"))))

dessine bien la polyligne.

 

Dans tous les cas, je préfèrerais faire :

(vl-cmdf "_.pline")
(mapcar 'vl-cmdf lpt)
(vl-cmdf "_close")]

ou, mieux parce que le mapcar n'est pas utile dans ce cas :

(vl-cmdf "_.pline")
(foreach p lpt (vl-cmdf p))
(vl-cmdf "_close")

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut,

Salut Gile,

 

J'ai toujours pensé que mapcar était implémentée un peu comme ça :

(defun map (f l)
 (if l
   (cons ((eval f) (car l)) (map f (cdr l)))
 )
)

Or ceci ne fonctionne pas avec quote (contrairement aux autres fonctions)

Il faut dire que le quote est un peu la fonction "originelle" du lisp, parfois j'en perds un peu la compréhension.

D'ailleur un mapcar quote, quoique logique, me paraissais assez rigolo

 

ou, mieux parce que le mapcar n'est pas utile dans ce cas :

(vl-cmdf "_.pline")
(foreach p lpt (vl-cmdf p))
(vl-cmdf "_close")

J'ai toujours utilisé le mapcar 'command par fainéantise,

et je croyais que le vl-cmdf était l'équivalent de command-s, obligeant à donner tous les arguments dès le début (c'est ce qu'explique l'aide lisp)

mais en fait vl-cmdf est un mix entre command et command-s, et à ce titre ne me sortira pas d'affaire:

j'ai eu des erreurs VVC: Internal error avec un simple (vl-cmdf "_redraw"), qui n'est même pas imbriqué dans un mapcar.

 

il y a des parties centrales de mes programmes pour lesquelle j'ai supprimé depuis longtemps la plupart des appels command par des methodes plus propres,

mais pour beaucoup de petits utilitaires, j'utilise command, et je vais avoir beaucoup de mal à migrer toutes ces petites routines.

----------------------------------------------------------------------

Site: https://www.g-eaux.fr

Blog: http://g-eaux.over-blog.com

  • 2 mois après...
Posté(e)

Bonjour,

 

Je viens seulement de découvrir ce sujet qui à également éveillé ma curiosité. Après quelques teste je vous en donne ma lecture.

Bizarre ou tout à fait logique ?

Logique et bizarre (peut être pas…)

 

La fonction quote n'est pas une fonction neutre, elle bloque l'évaluation de l'expression qui suit. Par exemple si on tentait une écriture équivalente à ce qui a été codé précédemment via une fonction lambda on aurait:

_$ (mapcar '(lambda (x) (quote x)) '(A B C D E))
(X X X X X)

 

Et sans fonction lambba on a:

_$ (mapcar 'quote '(A B C D E))
((quote E) (quote E) (quote E) (quote E) (quote E))

La fonction enveloppante lambda n'évaluant plus l'expression quote, c'est l'ensemble de l'expression qui est retourné. Plus précisément la dernière expression, je pense également qu'en interne la fonction est définie de façon récursive et que le quote doit bloquer successivement l'évaluation et donc la substitution des arguments dans la remontée des appels enveloppant.

 

Donc dans ce cas particulier propre au fonctionnement de la fonction quote, il faut "quoté" le quote (clin d'œil à l'entête du post ;) ) pour que cela fonctionne:

_$ (mapcar '(lambda (x) (list 'quote x)) '(A B C D E))
((QUOTE A) (QUOTE B) (QUOTE C) (QUOTE D) (QUOTE E))

 

Expression qui fonctionne très bien (également avec command) sous ma veille version 2007 à tester sur une version récente:

_$ (setq lpt '((-4007.29 77.6245) (-3836.77 115.533) (-3831.78 114.556) (-3832.16 112.594) (-3836.75 113.49) (-4006.85 75.6722)))
((-4007.29 77.6245) (-3836.77 115.533) (-3831.78 114.556) (-3832.16 112.594) (-3836.75 113.49) (-4006.85 75.6722))
_$ (eval (append '(VL-CMDF "_pline")  (mapcar '(lambda (x) (list 'quote x)) lpt) '("_close")))
T

 

Amicalement Bruno

Apprendre => Prendre => Rendre

Posté(e)

Salut,

J'ai toujours pensé que mapcar était implémentée un peu comme ça :

(defun map (f l)
 (if l
   (cons ((eval f) (car l)) (map f (cdr l)))
 )
)

Or ceci ne fonctionne pas avec quote (contrairement aux autres fonctions), par contre, en utilisant apply à la place de eval, ça marche :

(defun map (f l)
 (if l
   (cons (apply f (list (car l))) (map f (cdr l)))
 )
)

En fait ce qui pose problème sont les fonctions qualifiés de"formes spéciales", elles doivent être "quoté" et ne peuvent donc être évalués puis associés à leurs arguments comme les autres "opérateur Lisp", il faut impérativement construire l'expression puis évaluer cette dernière (avec un eval enveloppant).

 

Pour un mapcar générique sans apply, l'implémentation Lisp ressemble à quelque chose comme cela:

(defun map (f l)
 (if l
   (cons (eval (list f (car l))) (map f (cdr l)))
 )
)

 

Amicalement Bruno

Apprendre => Prendre => Rendre

Posté(e)

Pour un mapcar générique sans apply, l'implémentation Lisp ressemble à quelque chose comme cela:

(defun map (f l)
 (if l
   (cons (eval (list f (car l))) (map f (cdr l)))
 )
)

 

Après réflexion, l'écriture suivante me semble plus juste…

(defun map (f l)
 (if l
   (cons (eval (list f (list 'quote (car l)))) (map f (cdr l)))
 )
)

A+ Bruno

Apprendre => Prendre => Rendre

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité