• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. how to use setf_last

Stats

  • Replies 8
  • Subscribers 148
  • Views 364
  • Members are here 0

how to use setf_last

kkdesbois
kkdesbois 5 days ago

Hello, 

I can not understand the error message returned in the following example : 

A='("a" "b" "c" "d")
(setf_last A "e")

*** Error in routine cddr:
Message: *Error* cddr: argument #1 should be a list (type template = "l") at line 48 of file "*ciwInPort*" - "e"
Entering new debug toplevel due to error:

Is it possible to replace "d" by "e" without using the following syntax : 
(setf (car (last A)) "e")

Laurent.

  • Cancel
  • Sign in to reply
  • Andrew Beckett
    Andrew Beckett 5 days ago

    Hi Laurent,

    The whole point of the setf_* helper functions/macros is to allow the simple use of setf(place value) and then this is transformed into the right function with maybe more cryptic syntax. For example:

    expandMacroDeep('(setf (car (last A)) "e"))
    car(rplaca(last(A) "e"))

    You could (I guess) use setf_last directly, but you need to remember that last() is a list - so you'd need to use (setf_last (list "e") A) - note the arguments are also the opposite way around than you were using.

    I would strongly suggest you use setf rather than directly calling the helper function.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • kkdesbois
    kkdesbois 5 days ago in reply to Andrew Beckett

    Thanks for the prompt reply.
    I missed the point in the doc about the reversed arguments for the helper functions!
    I'll follow your suggestion

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Aurel B
    Aurel B 5 days ago

    Hi Laurent,

    As Andrew said it makes little sense to use setf_ helpers directly as they are wrappers around setter functions to normalize the syntax.

    If the thing that annoys you is purely the syntax, please note that there is a dedicated C-style syntax for self : 

    (car (last A)) := "e"

    Also if it's the car statement that feels weird, it is necessary with last, otherwise we wouldn't be able to differentiate an empty list from a list which contains nil as its last element.

    But it only means that last value to be setf has to be a list, so you can also do the following:

    (last A) := (list "e")

    ; I would avoid `(last A) := '( "e" )` which can lead to confusing behaviors

    And for completeness, if you get used to setf it is worth noting that pushf and popf exist. They are to push and pop what setf is to set.

    (I don't think push and pop were ever documented in Virtuoso though. But they are very basic and common Lisp macros. They are available in Core SKILL even when running the bare SKILL interpreter.)

    They are quite useful with tables using nil as default value. You can do things like : 

    grades_by_students = (makeTable t nil)

    (pushf 12 (grades_by_students["student_name"]))

    grades_by_students->??

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Aurel B
    Aurel B 5 days ago in reply to kkdesbois

    Not sure it's going to help you memorize it but if you were to build a self helper, you will realize that in a self_helper the value to set can only be the first argument.

    If you have a fancy getter function : 

    (defun fancy_getter ( positional_arg @optional optional_arg @rest args ) "Return whatever value" ... )

    To build a self_helper for it, you need to take all the getter arguments but also the value to set which is a necessary argument.

    The only way to make it necessary is to start with it. It will look like this : 

    (defun setf_fancy_getter ( value positional_arg @optional optional_arg @rest args ) "Set whatever value and return it" ... )

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Andrew Beckett
    Andrew Beckett 5 days ago in reply to Aurel B

    BTW you can also use defsetf to associate the update function (the helper) with the access function. Doesn't particularly make it easier to understand though ;-)

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • kkdesbois
    kkdesbois 5 days ago in reply to Aurel B

    Thank you both for the explanations.


    Aurélien, in your last example, are the following syntaxes identical?

    (pushf 12 (grades_by_students["student_name"]))

    (setf grades_by_students["student_name"] 12)

    grades_by_students["student_name"]=12

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Andrew Beckett
    Andrew Beckett 5 days ago in reply to kkdesbois

    pushf will push a new value onto the beginning of a list specified by the "place" in the second argument).

    Using setf or = (setq) would just assign the value directly into the array. There's no real benefit of using setf on a hash (array) other than the consistency of using setf. So the second two are equivalent (but differently implemented), but they are doing something quite different than the pushf (because that is pushing onto a list)

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel
  • Aurel B
    Aurel B 3 days ago in reply to kkdesbois

    (push elt l) <=> (setq list (cons elt l))

    (pushf 12 grades_by_students["students_name"])
    <=>
    (setf grades_by_students["students_name"] (cons 12 grades_by_students["students_name"]))

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information