Is it possible to push a lookup parameter into multiple block definitions using Autolisp - autolisp

I'll give a hypothetical example to demonstrate my problem. Imagine that I have a lookup parameter "Color" on a dynamic block definition for a chair and I've given it the possible values of "Red", "Blue", and "Green". Now I need to push this lookup parameter to tons and tons of other dynamic block definitions for other types of chairs. I don't want to have to go into the UI and the block editor for each definition and add this lookup parameter. Instead I would like to automate this by writing an Autolisp routine and passing in the different blocks.
Is this possible using Autolisp? Is it possible using any of the other AutoCAD APIs?
Note below:
I want to edit different block definitions, not references.
I don't want to use a block properties table because I'm already using that for other purposes.

In short: No, this functionality was never exposed to the LISP API.
Whilst you can retrieve and change the values of existing dynamic block parameters (using the getdynamicblockproperties method of a block reference object), you cannot create or modify dynamic block parameters within a block definition, nor will such objects be visible through the Visual LISP API.
Curiously, the parameters are visible when interrogating the DXF data of a block definition through Vanilla AutoLISP, by inspecting the ACAD_ENHANCEDBLOCK dictionary found within the Extension Dictionary of the BLOCK_RECORD entity:
(dictsearch
(cdr
(assoc 360
(entget
(cdr
(assoc 330
(entget
(tblobjname "block" "YourDynamicBlockName")
)
)
)
)
)
)
"acad_enhancedblock"
)
However, this area of DXF data is entirely undocumented and could likely produce unexpected and unstable results if modified directly, given that it isn't officially supported by the API.

Related

Why are class slots specified with keywords but accessed with symbols?

I have recently encountered a confusing dichotomy regarding structures in Lisp.
When creating a structure with (defstruct), we specify the slots by keyword (:slotname). But when accessing it, we use local symbols ('slotname).
Why? This makes no sense to me.
Also, doesn't this pollute the keyword package every time you declare a structure?
If I try to access the slots by keyword, I get confusing errors like:
When attempting to read the slot's value (slot-value), the slot :BALANCE is
missing from the object #S(ACCOUNT :BALANCE 1000 :CUSTOMER-NAME "John Doe").
I don't understand this message. It seems to be telling me that something right under my nose doesn't exist.
I have tried declaring the structure using local symbols; and also with unbound keywords (#:balance) and these don't work.
DEFSTRUCT is designed in the language standard in this way:
slot-names are not exposed
there is no specified way to get a list of slot-names of a structure class
there is no specified way to access a slot via a slot-name
thus at runtime there might be no slot-names
access to slots is optimized with accessor functions: static structure layout, inlined accessor functions, ...
Also explicitly:
slot-names are not allowed to be duplicate under string=. Thus slots foo::a and bar::a in the same structure class are not allowed
the effects of redefining a structure is undefined
The goal of structures is to provide fast record-like objects without costly features like redefinition, multiple inheritance, etc.
Thus using SLOT-VALUE to access structure slots is an extension of implementations, not a part of the defined language. SLOT-VALUE was introduced when CLOS was added to Common Lisp. Several implementations provide a way to access a structure slot via SLOT-VALUE. This then also requires that the implementation has kept track of slot names of that structure.
SLOT-VALUE is simply a newer API function, coming from CLOS for CLOS. Structures are an older feature, which was defined already in the first version of Common Lisp defined by the book CLtL1.
You used make-instance to create a class instance and then you are showing a struct, I am confused.
structs automatically build their accessor functions. You create it with make-account. Then you'd use account-balance instead of slot-value.
I don't know what is the expected behavior to use make-instance with a struct. While it seemed to work on my SBCL, you are not using structs right.
(defstruct account
(balance))
(make-account :balance 100)
#S(ACCOUNT :BALANCE 100)
(account-balance *)
100
With classes, you are free to name your accessor functions as you want.
;;(pseudocode)
(defclass bank-account ()
((balance :initform nil ;; otherwise it's unbound
:initarg :balance ;; to use with make-instance :balance
:accessor balance ;; or account-balance, as you wish.
)))
(make-instance 'bank-account :balance 200)
#<BANK-ACCOUNT {1009302A33}>
(balance *)
200
https://lispcookbook.github.io/cl-cookbook/data-structures.html#structures
http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm
the slot :BALANCE is missing from the object #S(ACCOUNT :BALANCE 1000 :CUSTOMER-NAME "John Doe").
The slot name is actually balance and the representation uses the generated initargs. With the class object, the error message might be less confusing:
When attempting to read the slot's value (slot-value), the slot :BALANCE is missing from the object #<BANK-ACCOUNT {1009302A33}>.
First of all, see Rainer's excellent answer on structures. In summary:
Objects defined with defstruct have named accessor functions, not named slots. Further the field names of these objects which are mentioned in the defstruct form must be distinct as strings, and so keywords are completely appropriate for use in constructor functions. Any use of slot-value on such objects is implementation-dependent, and indeed whether or not named slots exist at all is entirely implementation-dependent.
You generally want keyword arguments for the constructors for the reasons you want keyword arguments elsewhere: you don't want to have to painfully provide 49 optional arguments so you can specify the 50th. So it's reasonable that the default thing defstruct does is that. But you can completely override this if you want to, using a BOA constructor, which defstruct allows you to do. You can even have no constructor at all! As an example here is a rather perverse structure constructor: it does use keyword arguments, but not the ones you might naively expect.
(defstruct (foo
(:constructor
make-foo (&key ((:y x) 1) ((:x y) 2))))
y
x)
So the real question revolves around classes defined with defclass, which usually do have named slots and where slot-value does work.
So in this case there are really two parts to the annswer.
Firstly, as before, keyword arguments are really useful for constructors because no-one wants to have to remember 932 optional argument defaults. But defclass provides complete control over the mapping between keyword arguments and the slots they initialise, or whether they initialise slots at all or instead are passed to some initialize-instance method. You can just do anything you want here.
Secondly, you really want slot names for objects of classes defined with defclass to be symbols which live in packages. You definitely do not want this to happen:
(in-package "MY-PACKAGE")
(use-package "SOMEONE-ELSES-PACKAGE")
(defclass my-class (someone-elses-class)
((internal-implementation-slot ...)))
only to discover that you have just modified the definition of the someone-elses-package::internal-implementation-slot slot in someone-elses-class. That would be bad. So slot names are symbols which live in packages and the normal namespace control around packages works for them too: my-package::internal-implementation-slot and someone-elses-package::internal-implementation-slot are not (usually) the same thing.
Additionally, the whole keyword-symbol-argument / non-keyword-symbol-variable thing is, well, let's just say well-established:
(defun foo (&key (x 1))
... x ...)
Finally note, of course, that keyword arguments don't actually have to be keywords: it's generally convenient that they are because you need quotes otherwise, but:
(defclass silly ()
((foo :initarg foo
:accessor silly-foo)
(bar :initarg bar
:accessor silly-bar)))
And now
> (silly-foo (make-instance 'silly 'bar 3 'foo 9))
9

Modify Scilab/Xcos Block in Scilab 6 Gateway Function

I would like to modify an Xcos block from within a gateway function using the new (non-legacy) Scilab API, for example, replace the block's model property by a new model structure. In other words, do the same as the Scilab command(s):
m = scicos_model()
block.model = m
However, I did not manage to achieve this behavior with the functions from Scilab 6 API: a block created by standard_define() is correctly passed to my gateway function, where this argument is available as scilabVar of type 128. On the other hand, the Scilab help claims that a block is a "scilab tlist of type "Block" with fields : graphics, model, gui and doc".
Attempts
Assume scilabVar block taken from gateway function argument, string constants of type wchar_t[], scilabVar model holding the result of scicos_model():
Application of function scilab_setTListField (env, block, "model", model) returns error status (as its equivalents for MList and List do)
Knowing that property .model is at index 3, a setfield (3, model, block) called through scilab_call ("setfield", ...) also fails.
This is not surprising: when called directly from the Scilab command line, it ends up with
setfield: Wrong type for input argument #3: List expected. .
However, a getfield (3, block) works, so that at least read access to the block's data fields is possible.
An external helper function
function block = blockSetModel (block, model)
block.model = model
endfunction
also called through scilab_call("blockSetModel", ...) actually returns a block with changed model,
but the original block passed to this function remains unchanged.
Although ugly, this gives at least a way to construct an individual block structure
which needs to be returned as a copy.
Summary
So, is there simply a function missing in the API, which returns the TList (or whatever) behind a type 128 pointer variable?
Or is there any other approach to this problem I was unable to discover?
Background
The goal behind is to move the block definition task from the usual interfacing "gui" function (e.g. a Scilab script MyBlock.sci) into own C code. For this purpose, the interfacing function is reduced to a wrapper around a C gateway, which, for example, usesscilab_call ("standard_define",...) to create a new block when being called with parameter job=="define".
Modification of the contained model and graphics objects through the Scilab API works fine since these are standard list types. However, getting or setting these objects as attributes .model and .graphics of the
original block fails as described above.
Starting from Scilab/Xcos 6.0.0, the data-structure behind a block is no more an MList (or TList) so you cannot upgrade the model to your own MList. All the data behind are stored using a classical MVC within a C++ coded Block.hxx.
On each try you made, a serialization/deserialization happens to reconstruct the block model field as a Scilab value.
Could you describe what kind of field you want to append/edit regarding the block structure ? Some of the predefined fields might be enough to pass extra information.

When does lexical scoping binding take place - in runtime or compile time?

C language take scope binding during compile time (variable reference get fixed address - doesn't change at all), that is example of static scoping.
Elisp language take scope binding during run time (variable point to top of own personal reference stack, let/defun/... special forms add to the top of stack on entry from top on the leave - in that time capture modified), that is example of dynamic scoping.
What type of binding used in lexical scoping?
Such language as Common Lisp, Python, R, JavaScript state that they implement lexical scoping.
What technics are used in implementation for that languages?
I hear about environments that carried with function appearance. If I right - when was environments created?
Is it possible or usual to construct and bind environment to function by developer manually? Some thing like call( bind_env(make_env({buf: [...], len: 5}), myfunc) )
In short, lexical scoping takes place at compile time (or more precisely, at the time when the function definition is evaluated). Also, lexical scoping can be static scoping: this is how ML-languages (SML, OCaml, Haskell) do it.
Environments
Every function is defined in some environment. Also, each function creates its own local environment nested in enclosing environment. Top level environment is where all usual variables, functions (+, -, sin, map, etc.) and syntax (relevant for languages that can extend syntax, like Common Lisp, Scheme, Clojure) are defined.
Each function creates its own local environment nested in enclosing environment (e.g., top level or of other function). Function arguments and all local variables live in this environment. If function reference a variable or a function that is not defined in the local environment (called free in this environment) it is found in enclosing environment of the function definition (or higher in enclosing env of enclosing environment if it is not found there and so on). This is different from dynamic scoping where the value would be found in the environment from where the function is called.
I am going to illustrate this using Scheme:
y is free in this definition
(define (foo x)
(+ x y))
Here is y defined in top-level environment
(define y 1)
Introduce local 'y', but foo will use y from enclosing (top-level) environment of the definition. Hence, the result is 2 and not 11.
(let ((y 10))
(foo 1))
=> 2
You can also define a function (or a procedure in Scheme's terms) with a local environment enclosing it:
(define bar
(let ((y 100))
(lambda (x) (+ x y))))
(bar 1)
=> 101
Here procedure value bar is defined to be a procedure. Variable y is again free in the procedure body. But enclosing environment is created by let form in which y is defined to be 100. So, when bar is called, it is that value of y which is fetched and not top-level (in a dynamically scoped language it would have returned 2).
Answering your last question, it is possible to create your own environment manually, but it would be too much work and probably wouldn't be very efficient. When the language is implemented (for example, Scheme interpreter), that is exactly what the language developer is doing.
Good explanation of environments is shown in SICP, Chapter 3
Other comments
AFAIK, from Emacs 23, ELisp is using lexical scoping as well as dynamic scoping (similarly to Common Lisp, see below).
Common Lisp uses lexical scoping for local variables (introduced by let form) and dynamic scoping for global variables (they are also called special; it is possible to declare a local variable special, but it is rarely used) defined with defvar and defparameter. To distinguish them from lexically scoped variables, their names usually have "ear muffs", for example *standard-input*. Top-level functions are also special in CL, which can be rather dangerous: one can unknowingly alter behavior by shadowing top-level function. This why CL standard specifies the locks on standard library function to prevent their re-definition.
Scheme, in contrast, always uses lexical scoping. Dynamic scoping, however, is useful sometimes (Richard Stallman makes a good point on it). To overcome this, many Scheme implementations introduced so-called parameters (implemented using lexical scoping).
Languages like Common Lisp, Scheme, Clojure, Python keep a dynamic reference to a variable: you can construct the variable name from a string (intern a symbol in Lisp's terms) and find its value. More static languages, like C, OCaml or Haskell, cannot do that (unless some form of reflection is used). But this has a weak connection to what kind of scoping they use.

Separate Namespaces for Functions and Variables in Common Lisp versus Scheme

Scheme uses a single namespace for all variables, regardless of whether they are bound to functions or other types of values. Common Lisp separates the two, such that the identifier "hello" may refer to a function in one context, and a string in another.
(Note 1: This question needs an example of the above; feel free to edit it and add one, or e-mail the original author with it and I will do so.)
However, in some contexts, such as passing functions as parameters to other functions, the programmer must explicitly distinguish that he's specifying a function variable, rather than a non-function variable, by using #', as in:
(sort (list '(9 A) '(3 B) '(4 C)) #'< :key #'first)
I have always considered this to be a bit of a wart, but I've recently run across an argument that this is actually a feature:
...the
important distinction actually lies in the syntax of forms, not in the
type of objects. Without knowing anything about the runtime values
involved, it is quite clear that the first element of a function form
must be a function. CL takes this fact and makes it a part of the
language, along with macro and special forms which also can (and must)
be determined statically. So my question is: why would you want the
names of functions and the names of variables to be in the same
namespace, when the primary use of function names is to appear where a
variable name would rarely want to appear?
Consider the case of class names: why should a class named FOO prevent
the use of variables named FOO? The only time I would be referring the
class by the name FOO is in contexts which expect a class name. If, on
the rare occasion I need to get the class object which is bound to the
class name FOO, there is FIND-CLASS.
This argument does make some sense to me from experience; there is a similar case in Haskell with field names, which are also functions used to access the fields. This is a bit awkward:
data Point = Point { x, y :: Double {- lots of other fields as well --} }
isOrigin p = (x p == 0) && (y p == 0)
This is solved by a bit of extra syntax, made especially nice by the NamedFieldPuns extension:
isOrigin2 Point{x,y} = (x == 0) && (y == 0)
So, to the question, beyond consistency, what are the advantages and disadvantages, both for Common Lisp vs. Scheme and in general, of a single namespace for all values versus separate ones for functions and non-function values?
The two different approaches have names: Lisp-1 and Lisp-2. A Lisp-1 has a single namespace for both variables and functions (as in Scheme) while a Lisp-2 has separate namespaces for variables and functions (as in Common Lisp). I mention this because you may not be aware of the terminology since you didn't refer to it in your question.
Wikipedia refers to this debate:
Whether a separate namespace for functions is an advantage is a source of contention in the Lisp community. It is usually referred to as the Lisp-1 vs. Lisp-2 debate. Lisp-1 refers to Scheme's model and Lisp-2 refers to Common Lisp's model. These names were coined in a 1988 paper by Richard P. Gabriel and Kent Pitman, which extensively compares the two approaches.
Gabriel and Pitman's paper titled Technical Issues of Separation in Function Cells and Value Cells addresses this very issue.
Actually, as outlined in the paper by Richard Gabriel and Kent Pitman, the debate is about Lisp-5 against Lisp-6, since there are several other namespaces already there, in the paper are mentioned type names, tag names, block names, and declaration names. edit: this seems to be incorrect, as Rainer points out in the comment: Scheme actually seems to be a Lisp-1. The following is largely unaffected by this error, though.
Whether a symbol denotes something to be executed or something to be referred to is always clear from the context. Throwing functions and variables into the same namespace is primarily a restriction: the programmer cannot use the same name for a thing and an action. What a Lisp-5 gets out of this is just that some syntactic overhead for referencing something from a different namespace than what the current context implies is avoided. edit: this is not the whole picture, just the surface.
I know that Lisp-5 proponents like the fact that functions are data, and that this is expressed in the language core. I like the fact that I can call a list "list" and a car "car" without confusing my compiler, and functions are a fundamentally special kind of data anyway. edit: this is my main point: separate namespaces are not a wart at all.
I also liked what Pascal Constanza had to say about this.
I've met a similar distinction in Python (unified namespace) vs Ruby (distinct namespaces for methods vs non-methods). In that context, I prefer Python's approach -- for example, with that approach, if I want to make a list of things, some of which are functions while others aren't, I don't have to do anything different with their names, depending on their "function-ness", for example. Similar considerations apply to all cases in which function objects are to be bandied around rather than called (arguments to, and return values from, higher-order functions, etc, etc).
Non-functions can be called, too (if their classes define __call__, in the case of Python -- a special case of "operator overloading") so the "contextual distinction" isn't necessarily clear, either.
However, my "lisp-oid" experience is/was mostly with Scheme rather than Common Lisp, so I may be subconsciously biased by the familiarity with the uniform namespace that in the end comes from that experience.
The name of a function in Scheme is just a variable with the function as its value. Whether I do (define x (y) (z y)) or (let ((x (lambda (y) (z y)))), I'm defining a function that I can call. So the idea that "a variable name would rarely want to appear there" is kind of specious as far as Scheme is concerned.
Scheme is a characteristically functional language, so treating functions as data is one of its tenets. Having functions be a type of their own that's stored like all other data is a way of carrying on the idea.
The biggest downside I see, at least for Common Lisp, is understandability. We can all agree that it uses different namespaces for variables and functions, but how many does it have? In PAIP, Norvig showed that it has "at least seven" namespaces.
When one of the language's classic books, written by a highly respected programmer, can't even say for certain in a published book, I think there's a problem. I don't have a problem with multiple namespaces, but I wish the language was, at the least, simple enough that somebody could understand this aspect of it entirely.
I'm comfortable using the same symbol for a variable and for a function, but in the more obscure areas I resort to using different names out of fear (colliding namespaces can be really hard to debug!), and that really should never be the case.
There's good things to both approaches. However, I find that when it matters, I prefer having both a function LIST and a a variable LIST than having to spell one of them incorrectly.

Lambdas with captured variables

Consider the following line of code:
private void DoThis() {
int i = 5;
var repo = new ReportsRepository<RptCriteriaHint>();
// This does NOT work
var query1 = repo.Find(x => x.CriteriaTypeID == i).ToList<RptCriteriaHint>();
// This DOES work
var query1 = repo.Find(x => x.CriteriaTypeID == 5).ToList<RptCriteriaHint>();
}
So when I hardwire an actual number into the lambda function, it works fine. When I use a captured variable into the expression it comes back with the following error:
No mapping exists from object type
ReportBuilder.Reporter+<>c__DisplayClass0
to a known managed provider native
type.
Why? How can I fix it?
Technically, the correct way to fix this is for the framework that is accepting the expression tree from your lambda to evaluate the i reference; in other words, it's a LINQ framework limitation for some specific framework. What it is currently trying to do is interpret the i as a member access on some type known to it (the provider) from the database. Because of the way lambda variable capture works, the i local variable is actually a field on a hidden class, the one with the funny name, that the provider doesn't recognize.
So, it's a framework problem.
If you really must get by, you could construct the expression manually, like this:
ParameterExpression x = Expression.Parameter(typeof(RptCriteriaHint), "x");
var query = repo.Find(
Expression.Lambda<Func<RptCriteriaHint,bool>>(
Expression.Equal(
Expression.MakeMemberAccess(
x,
typeof(RptCriteriaHint).GetProperty("CriteriaTypeID")),
Expression.Constant(i)),
x)).ToList();
... but that's just masochism.
Your comment on this entry prompts me to explain further.
Lambdas are convertible into one of two types: a delegate with the correct signature, or an Expression<TDelegate> of the correct signature. LINQ to external databases (as opposed to any kind of in-memory query) works using the second kind of conversion.
The compiler converts lambda expressions into expression trees, roughly speaking, by:
The syntax tree is parsed by the compiler - this happens for all code.
The syntax tree is rewritten after taking into account variable capture. Capturing variables is just like in a normal delegate or lambda - so display classes get created, and captured locals get moved into them (this is the same behaviour as variable capture in C# 2.0 anonymous delegates).
The new syntax tree is converted into a series of calls to the Expression class so that, at runtime, an object tree is created that faithfully represents the parsed text.
LINQ to external data sources is supposed to take this expression tree and interpret it for its semantic content, and interpret symbolic expressions inside the tree as either referring to things specific to its context (e.g. columns in the DB), or immediate values to convert. Usually, System.Reflection is used to look for framework-specific attributes to guide this conversion.
However, it looks like SubSonic is not properly treating symbolic references that it cannot find domain-specific correspondences for; rather than evaluating the symbolic references, it's just punting. Thus, it's a SubSonic problem.