• 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. nconc with (back)quote'd list constants

Stats

  • Locked Locked
  • Replies 11
  • Subscribers 144
  • Views 4500
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nconc with (back)quote'd list constants

tweeks
tweeks over 11 years ago

Google says: "Avoid nconc!"

http://google-styleguide.googlecode.com/svn/trunk/lispguide.xml#Avoid_NCONC

They recommend to use "mappend" instead, which you could naively define this way (naive because it's O(n^2)!):

(defun mappend (fn list "ul")
  "Append the results of calling fn on each element of list.
  Like mapcan, but uses append instead of nconc."
  (foldl1 append (mapcar fn list)))

(defun foldl1 (function list "ul")
  (if (null list)
      (error "foldl1: empty list")
      (foldl function (car list) (cdr list))))

(defun foldl (function initial list "ugl")
  (let ((result initial))
    (foreach mapc element list
      (setq result (function result element)))
    result))

If you don't see the danger, try this:

ILS-> (mappend (lambda (x) '(t)) '(1 2 3))
(t t t)
ILS-> (mapcan (lambda (x) '(t)) '(1 2 3))

The mappend version works correctly, but the mapcan version sends the interpreter into an infinite loop! 

Explanation: mapcan applies the lambda to 1, and nconcs the result--the constant '(t) list returned by the lambda--to itself, resulting in a circular list of length one, where the car is t and the cdr is its own car.  The next iteration, mapcan applies the lambda to 2, only this time nconc never returns, because it's too busy trying to find the end of an endless list....

I guess I'll have to write my own (foreach mappend....) to use in place of the more dangerous (foreach mapcan...).

  • Cancel
Parents
  • tweeks
    tweeks over 11 years ago

    Andrew Beckett said:

    I don't think there would be any benefit in doing that. tconc and lconc still destructively modify the list - and each time you call them it has to do a cdr to find the end of the list (not that expensive, but mapcan is more direct, I think).

    That is true.  My thinking was, if you're going to append 100 lists (or n lists in general) to an initial list, then it's faster to create a tconc structure and call lconc 100 times than to call append or nconc 100 times, because then you only need to walk down the initial list once.  Indeed, this would seem to be tconc's raison d'être. 

    Hey wait a minute--shouldn't mapcan use tconc internally rather than nconc?

    theopaone said:
     

    I was looking at name spaces to give us the ability to create packages, this is absolutely important to PDK development and delivery cycles. If the code is developed within the PDK version namespace, the same function can exist in VM in multiple namespace and my pcell would evaluate in the proper version of the namespace.

    You mean using the SKILL makeNamespace() mechanism?  Andrew said it is not ready for primetime.

    However, since environments are first-class in SKILL++, I think someone could make a pretty good namespace/module/package system out of them.... :)  I wish someone would do that and post it here!

     

    theopaone said:

     Much of duplicate function problem is legacy, where application developers needed particular functionality and created their own, applying their own knowledge of lisp and naming conventions to the implementation. Although naming rules may have been established for the initial development, the tools are built by application developers and in the past (long ago, in a valley far away), the naming guidance was not strictly enforced. When I was there, Virtuoso R&D had engaged in major efforts to increase the software quality with methodologies such as design and code reviews to minimize these issues. Quality has improved greatly since I left. {8^)

    Once a command is created and used, even internally, they can be hard to factor out without a giant review of the existing code. Some of them have evolved into aliases but others are buried in contexts and the developers are long gone. If, as a customer, I am using set_car and you eliminate it, you just broke my design flow. And what if my source code is no longer available (I blame the guy before me)...

    Ted

    Haha!  Thank you very much for the inside perspective, Ted. :)

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • tweeks
    tweeks over 11 years ago

    Andrew Beckett said:

    I don't think there would be any benefit in doing that. tconc and lconc still destructively modify the list - and each time you call them it has to do a cdr to find the end of the list (not that expensive, but mapcan is more direct, I think).

    That is true.  My thinking was, if you're going to append 100 lists (or n lists in general) to an initial list, then it's faster to create a tconc structure and call lconc 100 times than to call append or nconc 100 times, because then you only need to walk down the initial list once.  Indeed, this would seem to be tconc's raison d'être. 

    Hey wait a minute--shouldn't mapcan use tconc internally rather than nconc?

    theopaone said:
     

    I was looking at name spaces to give us the ability to create packages, this is absolutely important to PDK development and delivery cycles. If the code is developed within the PDK version namespace, the same function can exist in VM in multiple namespace and my pcell would evaluate in the proper version of the namespace.

    You mean using the SKILL makeNamespace() mechanism?  Andrew said it is not ready for primetime.

    However, since environments are first-class in SKILL++, I think someone could make a pretty good namespace/module/package system out of them.... :)  I wish someone would do that and post it here!

     

    theopaone said:

     Much of duplicate function problem is legacy, where application developers needed particular functionality and created their own, applying their own knowledge of lisp and naming conventions to the implementation. Although naming rules may have been established for the initial development, the tools are built by application developers and in the past (long ago, in a valley far away), the naming guidance was not strictly enforced. When I was there, Virtuoso R&D had engaged in major efforts to increase the software quality with methodologies such as design and code reviews to minimize these issues. Quality has improved greatly since I left. {8^)

    Once a command is created and used, even internally, they can be hard to factor out without a giant review of the existing code. Some of them have evolved into aliases but others are buried in contexts and the developers are long gone. If, as a customer, I am using set_car and you eliminate it, you just broke my design flow. And what if my source code is no longer available (I blame the guy before me)...

    Ted

    Haha!  Thank you very much for the inside perspective, Ted. :)

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

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