Author Topic: Cannot compile to VLX a loooooog PROGN  (Read 8590 times)

0 Members and 1 Guest are viewing this topic.

Peter2

  • Swamp Rat
  • Posts: 653
Cannot compile to VLX a loooooog PROGN
« on: February 17, 2015, 06:19:25 AM »
EDIT -  conclusion / solution:
Code - Auto/Visual Lisp: [Select]
  1. - progn is limited to 253(-256?) statements
  2. - there is no "solution", the situation has to be avoided
----------------------------------------------------------
This is more an info than a question (also a solution is welcomed ..)

I had a code like
Code - Auto/Visual Lisp: [Select]
  1. (if (= value 1)
  2.     (progn
  3.         (...... following 330 lines of code)
  4.     ) ; end progn
  5.     (progn
  6.        (....few lines)
  7.     )
  8. )

It works fine and correct as LSP-file, but when compiling it to VLX I got a message
Code - Auto/Visual Lisp: [Select]
  1. Error: Too many arguments:
  2.     (progn ...
  3. )
I solved it with the creation of two subroutines.

Not urgent question:
- Can it be confirmed?
- Can it be solved?

Thanks
« Last Edit: February 18, 2015, 09:22:01 AM by Peter2 »
Peter

AutoCAD Map 3D 2023 German (so some technical terms will be badly retranslated to English)
BricsCAD V23

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Cannot compile to VLX a loooooog PROGN
« Reply #1 on: February 17, 2015, 08:45:57 AM »
Quite possible that compiling would tend to make functions have a maximum argument count. Since everything in Lisp is a function, even defun is a function never mind progn, it means that your code is passed as arguments into that function. So long argument counts can very easily fail to compile. Not sure what the limits are, but at a guess I'd say around the 250 mark.

It's actually good practise to keep your code in small bits, even ignoring this possible limitation due to compiling. The rule of thumb is that if any defun is more than one screen height, you should try to split it.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

rkmcswain

  • Swamp Rat
  • Posts: 978
Re: Cannot compile to VLX a loooooog PROGN
« Reply #2 on: February 17, 2015, 11:08:55 AM »
I don't recall exactly when or where I've seen that, but that error looks familiar...

Can you use (cond) instead of (if)... IIRC, that is how I solved it.


EDIT: Can confirm that (if) generates the compile error and (cond) does not. It looks like (progn) might be the culprit. (And I used over 1200 lines.)
« Last Edit: February 17, 2015, 11:15:28 AM by rkmcswain »

ymg

  • Guest
Re: Cannot compile to VLX a loooooog PROGN
« Reply #3 on: February 17, 2015, 05:45:05 PM »
I ran into this problem quite a while ago.

Turn out that a progn is limited to 256 statements.

I remember settling it by removing multiple setq lines and  replacing it
with a single setq followed by the series of variables to set.

This counts a single statement.

One of the reason I hate! progn

ymg
« Last Edit: February 17, 2015, 05:59:50 PM by ymg »

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Cannot compile to VLX a loooooog PROGN
« Reply #4 on: February 18, 2015, 05:43:34 AM »
as an example, for testing long progn:
Code - Auto/Visual Lisp: [Select]
  1. (defun test-progn (/ f)
  2.   (setq f (open (strcat (getenv "USERPROFILE") "\\Desktop\\test.lsp") "w"))
  3.   (princ "(defun c:test (/ i)
  4.      (if (setq i(getint\"\\nEnter a number:\") )
  5.        (progn"
  6.          f
  7.   )
  8.   (repeat 253 (princ "\n(setq i (1+ i))" f))
  9.   ;; or repeat 600
  10.   (princ " (alert (itoa i)) (princ))))" f)
  11.   (close f)
  12.   (princ)
  13. )
Max length progn = 253
if check code length 254:
Code: [Select]
[CHECKING TEXT test.lsp loading...]
.
; error: too many arguments: (PROGN (SETQ I ( ... )) (SETQ I ( ... )) (SETQ I ( ... )) ... )
; Check done.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Cannot compile to VLX a loooooog PROGN
« Reply #5 on: February 18, 2015, 05:48:00 AM »
other way:
Code: [Select]
(progn
  (progn ...)
  ...
  (progn ...)
  )

Code - Auto/Visual Lisp: [Select]
  1. (defun test-progn (/ f)
  2.   (setq f (open (strcat (getenv "USERPROFILE") "\\Desktop\\test.lsp") "w"))
  3.   (princ "(defun c:test (/ i)
  4.      (if (setq i(getint\"\\nEnter a number:\") )
  5.        (progn"
  6.          f
  7.   )
  8.   (repeat 200
  9.     (princ "\n(progn " f)
  10.     (repeat 200 (princ "\n(setq i (1+ i))" f))
  11.     (princ "\n)" f)
  12.   )
  13.   (princ " (alert (itoa i)) (princ))))" f)
  14.   (close f)
  15.   (princ)
  16. )

Peter2

  • Swamp Rat
  • Posts: 653
Re: Cannot compile to VLX a loooooog PROGN
« Reply #6 on: February 18, 2015, 06:13:19 AM »
Thanks to all for the postings. The conclusion is:
Code - Auto/Visual Lisp: [Select]
  1. - progn is limited to 253(-256?) statements
  2. - there is no "solution", the situation has to be avoided
« Last Edit: February 18, 2015, 09:22:26 AM by Peter2 »
Peter

AutoCAD Map 3D 2023 German (so some technical terms will be badly retranslated to English)
BricsCAD V23

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Cannot compile to VLX a loooooog PROGN
« Reply #7 on: February 18, 2015, 07:14:28 AM »
No.
It's either 254 or 256 statements. ( figures quoted, not tested.)

and Statements are different from arguments.

I'd investigate calling a function instead of making your progn that length as a first test to eliminate the failure.



kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Cannot compile to VLX a loooooog PROGN
« Reply #8 on: February 18, 2015, 07:35:11 AM »
No.
It's either 254 or 256 statements. ( figures quoted, not tested.)

and Statements are different from arguments.

I'd investigate calling a function instead of making your progn that length as a first test to eliminate the failure.

I checked, the maximum list of 253 elements.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Cannot compile to VLX a loooooog PROGN
« Reply #9 on: February 18, 2015, 09:43:23 AM »
Take this for what it's worth but if you are running into a problem with progn's limits it speaks more to the structure of one's programming than it does of said limits. Subtitle: Properly modularized code will never breach these limits. To wit, I have source code files approaching one hundred thousand lines of code and have never run up against any related limits.

An aside, progn is very useful for compartmentalizing one's code, especially if one is using a programmer's editor (*cough* UltraEdit) capable of intelligent code collapsing. See the following for scaled down example.

Code: [Select]
(progn ;; ======================================================= FILENAME.LSP

    (progn ;; ======================================= Error Trapping Functions

        (defun _Try ( try_statement / try_catch try_result )

            ;;  Trap the execution af arbitry statements. Cache
            ;;  errors in a LIFO error stack should examination
            ;;  be desired by the caller.
            ;;
            ;;  If the caller establishes a local var of *try_errors*
            ;;  any cashed error msgs are solely for that function,
            ;;  otherwise they are global.

            (if
                (vl-catch-all-error-p
                    (setq try_catch
                        (vl-catch-all-apply
                            (function
                                (lambda ( )
                                    (setq try_result (eval try_statement))
                                )
                            )
                        )
                    )
                )
                (setq *try_errors* ;; lexical global
                    (cons
                        (list
                            try_statement
                            (vl-catch-all-error-message try_catch)
                        )
                        *try_errors*
                    )
                )
            )

            try_result

        )
       
    )
   
    (progn ;; ================================================== AEC Functions

        (defun _GetAecDwgUnits ( doc / aec_vars_dwg_setup )

            (_Try
               '(setq aec_vars_dwg_setup
                    (vla-item
                        (vla-item (vla-get-dictionaries doc) "AEC_VARS")
                        "AEC_VARS_DWG_SETUP"
                    )
                )
            )

            aec_vars_dwg_setup

        )

        (defun _KillAECBecauseItIsEvil ( doc / aec_vars_dwg_setup result )

            ;;  Inform user of result, return kill state to caller.

            (if (setq aec_vars_dwg_setup (_GetAecDwgUnits doc))
                (progn
                    (princ "AecDwgUnits entry found")
                    (_Try
                       '(progn
                            (vla-delete aec_vars_dwg_setup)
                            (setq result (vlax-erased-p aec_vars_dwg_setup))
                        )
                    )
                    (if result
                        (princ " [deleted].\n")
                        (princ " [could not delete].\n")
                    )
                    result
                )
                (progn
                    (princ "No AecDwgUnits entry found.\n")
                    nil
                )
            )
        )
    )

    (progn ;; =================================================== AEC Commands

        (defun c:KillAEC ( / aec_vars aec_vars_dwg_setup )

            (vl-load-com)

            (_KillAECBecauseItIsEvil (vla-get-activedocument (vlax-get-acad-object)))

            ;;  This would also work for the current drawing:
            ;;
            ;;      (if (setq aec_vars (dictsearch (namedobjdict) "AEC_VARS"))
            ;;          (if (setq aec_vars_dwg_setup
            ;;                  (cdadr (member '(3 . "AEC_VARS_DWG_SETUP") aec_vars))
            ;;              )
            ;;              (progn
            ;;                  (entdel aec_vars_dwg_setup)
            ;;                  (princ "AecDwgUnits havebeen removed.\n")
            ;;              )
            ;;              (princ "No worries, AecDwgUnits are not present.\n")
            ;;          )
            ;;          (princ "No worries, AecDwgUnits are not present.\n")
            ;;      )
            ;;
            ;;  Using the activeX method affords the ability to (potentially)
            ;;  perform the "cleansing" via objectdbx, ergo the penning of
            ;;  function _KillAECBecauseItIsEvil.

            (princ)

        )

    )
   
    (progn ;; ======================================================== On Load
   
        (princ "FILENAME loaded\n")

        (princ)
       
    )       

)

And yes, all my lisp source files start and end with a progn construct so I can copy the whole mess to the clipboard and paste to AutoCAD's command line, primarily useful when initially developing, but also useful to keep things segregated when combining files.

/2¢
« Last Edit: February 18, 2015, 09:51:50 AM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

ElpanovEvgeniy

  • Water Moccasin
  • Posts: 1569
  • Moscow (Russia)
Re: Cannot compile to VLX a loooooog PROGN
« Reply #10 on: February 18, 2015, 09:57:54 AM »

Code: [Select]
(progn ;; ======================================================= FILENAME.LSP

    (progn ;; ======================================= Error Trapping Functions

       ..............

And yes, all my lisp source files start and end with a progn construct so I can copy the whole mess to the clipboard and paste to AutoCAD's command line, primarily useful when initially developing, but also useful to keep things segregated when combining files.

/2¢

Yes, I also use progn for easy separation of pieces of code (like You).

The size of my biggest project ~ 400 000 rows (4.5 MB as VLX)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Cannot compile to VLX a loooooog PROGN
« Reply #11 on: February 18, 2015, 10:09:38 AM »
Subtitle: Properly modularized code will never breach these limits. To wit, I have source code files approaching one hundred thousand lines of code and have never run up against any related limits.
In full agreement. If you run into this problem, you should refactor your code due to other reasons. Basically what I was alluding to here:

It's actually good practise to keep your code in small bits, even ignoring this possible limitation due to compiling. The rule of thumb is that if any defun is more than one screen height, you should try to split it.

Though I tend to rather create a new file for those groupings instead of wrapping them into progns. But your idea makes a lot of sense too, especially if you don't use VLIDE.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

ribarm

  • Gator
  • Posts: 3282
  • Marko Ribar, architect
Re: Cannot compile to VLX a loooooog PROGN
« Reply #12 on: November 26, 2016, 09:21:17 AM »
If I can jump in... This issue is happening only when compiling lsp to vlx, or if you use checking from VLIDE... Otherwise (progn) have no limitations and I tend to keep lisp files not compiled - better to make copy and don't worry if I loose code - I always have copy in programmable form so that I and everyone can use it and see what it does... Similar like (setq) test here : https://www.theswamp.org/index.php?topic=52143.msg572836#msg572836 , here is my testing code...

Code: [Select]
(defun c:testprogn ( / f )
  (setq k 0)
  (while t
    (setq f (open "c:/SHARED FOLDER/ttt-progn.lsp" "w"))
    (write-line "(if t (progn" f)
    (repeat (setq k (1+ k))
      (write-line "(setq a 1)" f)
    )
    (write-line "))" f)
    (close f)
    (load "c:/SHARED FOLDER/ttt-progn.lsp")
  )
)

There is no problem in loading long (progn) inside plain lisp, only when checking through VLIDE which also have its limits with length of rows of code - apparently limit is 1000000 lines...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Peter2

  • Swamp Rat
  • Posts: 653
Re: Cannot compile to VLX a loooooog PROGN
« Reply #13 on: August 23, 2018, 10:14:59 AM »
Problem to be continued with "list" ...

I create a list, consisting of lists:

Code: [Select]
(setq *myListe* (list
(list "Line 1" "1000" "Jim" "John" "20181122" "20170914" "2019" "ab" "123" "NEIN")
(list "Line 2" "1000" "x" "y" "20181122" "20170914" "2019" "ab" "123" "NEIN")
.....
...
(list "Line 255" "1000" "f" "g" "20181122" "20170914" "2019" "ab" "123" "NEIN")
))
With a maximum number of 255 lists the compilation to FAS / VLX runs fine.
If the list has more than 255 lists, I get the vlide-report

Code: [Select]
[COMPILING C:/TEMP/test.lsp]
;
; Warndung: Unsichere Neudefinition von LIST-Symbol erzeugt Konflikt mit Übersetzung von LIST (Langliste) LIST
; === STATISTIK: -top-
;            Externe globale Variablen sind (*myLISTE*)
;            Zu verknüpfende Funktionsaufrufe (LIST)
;            Nicht verknüpfte Funktionsaufrufe (LIST)


This seems to say:

[COMPILING C:/TEMP/test.lsp]
;
; Warning: Unsecure new definition of LIST-Symbol creates conflict with translation(???) of LIST (long list??) LIST
; === STATISTIK: -top-
;            External global variable are (*myLISTE*)
;            function-calls to be connected (LIST)
;            not connected funtion-calls (LIST)

Nevertheless the created fas seem to work fine ...

Any experience with this behaviour?
Any other comments?

Thanks

Peter
Peter

AutoCAD Map 3D 2023 German (so some technical terms will be badly retranslated to English)
BricsCAD V23

JohnK

  • Administrator
  • Seagull
  • Posts: 10651
Re: Cannot compile to VLX a loooooog PROGN
« Reply #14 on: August 23, 2018, 12:14:52 PM »
No experience with this issue but I suppose I can proffer up a cheap comment (2 cents) or two.

Why so many lists? Why not store them in text files to be read into on an as needed basis?

Discussing the elephant in the room: I cant imagine a lisp program of these sizes; I don't remember the sizes of some of my larger lisp procedures but I imagine it was in the #,000 line ranges not ##,000 or ###,000 line range. Allowing a program to get that large hurts maintainability and invites more investment then necessary/practical.

* At that size (> #,000), you'd be better off writing programs to generate the code as you need it.
* I also think you need to spend time separating the interface from the engine.
* You might also think about a different data structure (s), such as a Binary Search Tree, -i.e. don't store redundant data, remove commonalities. EG: To get your feet wet on the subject you can check out Huffman coding [ https://en.wikipedia.org/wiki/Huffman_coding ]
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org