View Full Version : Common Lisp Object System (CLOS) Syntax
peter
2014-01-16, 05:54 PM
Lets discuss common lisp object system syntax here
BlackBox
2014-01-16, 06:02 PM
I too prefer code that is more 'readable', even at the cost of some code efficiency.
"It's just that these days they're considered bad practice"
I like the reddick naming convention, it is out of favor.
I like objDatabase compared to db.
I do not like reading abbreviations but rather read full descriptive variable names.
I do not always agree with ms on best practice. IMHO...
To my mind, objDatabase is actually less descript, if the Type being referenced is Database, and not Object (we're coding in object-oriented languages, never mind Dynamic Type):
Object objDatabase;
Database db;
As a generalization, I tend to name my variables for their Type, and /or Property name where applicable.
peter
2014-01-16, 10:58 PM
Never mind the minutia...
I am trying to find the correct syntax for passing an expression to a function. Like the predicate, action, func expressions.
I want to create the ability to pass an expression to a .net function and have it be a wrapper that evaluates it.
So much of the code is redundant, with maybe one or two lines different...
I want to pass the two lines as an argument.
I here in net 5.0 they are returning the compile at runtime evaluate expression like from vb6.
Currently most syntax in .net corresponds to the (vla-put-color obj 1) in lisp. I want the (vlax-put obj "color" 1) syntax so I can pass a property to the function and its new value.
And not just the gettype.getproperties(), but also the specific properties for the specific object I am passing.
On the previous topic...
As I understand it... the database and everything else in object oriented programming for that matter is an object.
I like obj, col, dbl, str, lst, etc... I tried coming up with different prefixes depending on the type of object, but because we have too many cooks in the kitchen, with syntax and functions all over the place
I reverted back to the obj prefix. It is just the way I like to read it.
P=
I have the
BlackBox
2014-01-16, 11:03 PM
I want the (vlax-put obj "color" 1) syntax so I can pass a property to the function and its new value.
I know of no way to pass a VL Objects via ResultBuffer... Only ObjectId.
peter
2014-01-17, 02:29 AM
I understand that you cannot use com vla-objects in .net...
What I was getting at was a way to specify the property name as a variable.
objEntity.ColorIndex = 1
Is the usual way in .net to set a variable
propertyput(objEntity, "ColorIndex", 1)
Is what I want to be able to do.
That way I can pass the property name and value to the .net function from lisp and manipulate the .net object.
Peter
irneb
2014-01-17, 05:03 AM
propertyput(objEntity, "ColorIndex", 1)That's called message-passing, and it's actually the way most OOP is done in Lisp. E.g. Common Lisp's CLOS (Common Lisp Object System) is designed exactly like this: http://www.cs.northwestern.edu/academics/courses/325/readings/clos.php And it's also how Vital Lisp originally implemented the tie-in onto ActiveX (vlax-put, vlax-get & vlax-invoke).
You're absolutely on the correct track. I was thinking along the same lines. It should even be possible to use reflection so you don't need to program in every method/property through something like a switch statement.
peter
2014-01-21, 07:41 AM
I too prefer code that is more 'readable', even at the cost of some code efficiency.
To my mind, objDatabase is actually less descript, if the Type being referenced is Database, and not Object (we're coding in object-oriented languages, never mind Dynamic Type):
Object objDatabase;
Database db;
As a generalization, I tend to name my variables for their Type, and /or Property name where applicable.
I have been thinking about this discussion.
My thoughts are I avoid abbreviations.
So
DataBase dataBase;
or
Database objDataBase;
would be my preference.
Scott Mcfarlanes class names at AU this year (c# code best practices) used the
Database database;
style
I would like to work with the contributors of these threads to find some middle ground in our variable naming styles that we could all use.
I find abbreviations cryptic and difficult to understand unless I write them.
The idea here is to help everyone understand, especially newcomers...
Thoughts?
irneb
2014-01-21, 10:41 AM
I definitely agree that in most cases abbreviations could make for less readable code. It's just that so many of us are "used to" some form of abbreviation - especially those of use who've come from the time when your variables had a maximum name-length (or like in AutoLisp using extra RAM for longer names). Of course that's no excuse for using cryptic names.
I try to work on the principle where I name a function and/or variable such that they wouldn't need any comment to make it clear as to what's happening in the code. Though I do find myself sometimes falling back to old habits. Where I'm not too sure though is if the name needs to include the type-info, for me it makes less sense in a statistic typed language (like C#, not using var) than in a dynamic typed language (like Lisp). But even then I'd say that rather loose the type from the name if that might make the understanding better. E.g. Say you want to store a list of layer names (perhaps selected by the user through a dialog), IMO calling that lstLayers is less readable than simply calling it Layers.
Another thing which I hope I can someday un-learn is to use descriptive names instead of generalizations. E.g. how many times have I seen (and used myself) a variable name like LST to hold a list of values? Even a better (though not descriptive enough) name would have been Values. Best would be to name it according to what those values would be used for, e.g. a list of layer names should then rather be called Layers.
peter
2014-01-21, 04:20 PM
I use lstSublist or lstPoint in my lisp programming.
I do not use abbreviations any more and I agree with:
" I name a function and/or variable such that they wouldn't need any comment to make it clear as to what's happening in the code"
lstOfStrings
The other thing I have been promoting is a verb last function or sub naming convention like SplashScreenShow compared to ShowSplashScreen.
Or AttributesGet compared to GetAttributes. Which to my view is backwards and makes it difficult to organize code alphabetically.
You end up with all the get functions together instead of all of the attributes functions together...
WHat is you feeling on
Dim objDatabase as Database
or
Dim dataBase as Database
?
Peter
peter
2014-01-21, 10:32 PM
On the topic CLOS and trying to create the ability to change properties with a general function that accepts the object, propertyname and newvalue
Here are two general functions to get and put .net properties from lisp using .net.
This is copied from a thread I participated in on the LISP list a few months ago.
Imports System
Imports System.Reflection
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Runtime
Public Class LISPClass
' syntax (PropertyPut (entlast) "width" 10.0)
<LispFunction("PropertyPut")> _
Public Function PropertyPut(ByVal rbfLISPArguments As ResultBuffer)
On Error GoTo OnError
Dim arrLISPArguments As TypedValue() = rbfLISPArguments.AsArray
If arrLISPArguments.Length = 3 Then
Dim oidSelection As ObjectId = arrLISPArguments(0).Value
Dim strPropertyName As String = arrLISPArguments(1).Value
Dim objValue As Object = arrLISPArguments(2).Value
Dim objDocument As Document = Application.DocumentManager.MdiActiveDocument
Using objTransaction As Transaction = objDocument.Database.TransactionManager.StartTransaction()
Dim objSelection As Entity = CType(oidSelection.GetObject(OpenMode.ForWrite), Entity)
Dim lstProperties As IList(Of PropertyInfo) = New List(Of PropertyInfo)(objSelection.GetType().GetProperties())
Dim intIndex As Integer = PropertyInfoAvailable(lstProperties, strPropertyName)
If Not intIndex = Nothing Then
Dim infProperty As PropertyInfo = lstProperties.Item(intIndex)
If infProperty.CanRead = True And infProperty.CanWrite = True Then
infProperty.SetValue(objSelection, objValue, Nothing)
objTransaction.Commit()
objTransaction.Dispose()
Return New TypedValue(LispDataType.T_atom, -1)
End If
End If
objTransaction.Dispose()
End Using
End If
OnError: Return New TypedValue(LispDataType.Nil, -1)
End Function
' syntax (PropertyGet (entlast) "width")
<LispFunction("PropertyGet")> _
Public Function PropertyGet(ByVal rbfLISPArguments As ResultBuffer)
On Error GoTo OnError
Dim arrLISPArguments As TypedValue() = rbfLISPArguments.AsArray
If arrLISPArguments.Length = 2 Then
Dim oidSelection As ObjectId = arrLISPArguments(0).Value
Dim strPropertyName As String = arrLISPArguments(1).Value
Dim objDocument As Document = Application.DocumentManager.MdiActiveDocument
Using objTransaction As Transaction = objDocument.Database.TransactionManager.StartTransaction()
Dim objSelection As Entity = CType(oidSelection.GetObject(OpenMode.ForRead), Entity)
Dim lstProperties As IList(Of PropertyInfo) = New List(Of PropertyInfo)(objSelection.GetType().GetProperties())
Dim intIndex As Integer = PropertyInfoAvailable(lstProperties, strPropertyName)
If Not intIndex = Nothing Then
Dim infProperty As PropertyInfo = lstProperties.Item(intIndex)
If infProperty.CanRead = True And infProperty.CanWrite = True Then
Dim objValue As Object = infProperty.GetValue(objSelection, Nothing, Nothing, Nothing, Nothing)
objTransaction.Commit()
objTransaction.Dispose()
Return objValue
End If
End If
objTransaction.Dispose()
End Using
End If
OnError: Return New TypedValue(LispDataType.Nil, -1)
End Function
Public Shared Function PropertyInfoAvailable(ByVal lstProperties As IList(Of PropertyInfo), ByVal strProperty As String)
On Error GoTo OnError
For Each infProperty As PropertyInfo In lstProperties
If infProperty.Name.ToString.ToUpper = strProperty.ToUpper Then
Return lstProperties.IndexOf(infProperty)
End If
Next
OnError: Return Nothing
End Function
It is a place to start.
irneb
2014-01-22, 05:19 AM
The other thing I have been promoting is a verb last function or sub naming convention like SplashScreenShow compared to ShowSplashScreen.I'm with you on this. It also follows the normal OO naming in C#/VB.Net (or for that matter all dot-notation OO languages), e.g. SplashScreen.Show(). Though if you convert it into a CLOS method, you'd get one of 2 versions:
General purpose: (InvokeMethod SplashScreen 'Show)
Specific method: (Show SplashScreen)
WHat is you feeling on
Dim objDatabase as Database
or
Dim dataBase as DatabaseNot too sure here. Personally I don't feel that the obj prefix does anything to help, I actually think it may detract from the understanding (e.g. is it a database of objects - i.e. entities in the DWG; or is the variable an object type, just per chance containing a "database"?)
Also the word "database" doesn't say much beyond that it's a query-able collection with multiple key(s) and value(s) per item, probably indexed on all keys and some values. Here also there's a bit ambiguous even from the start, is it:
The "database" of entities in the drawing - i.e. a collection object containing references to each entity (graphical or otherwise)
A database like a relational DB with multiple tables, relationships, built-in queries, etc.
If the 1st, I'd probably prefer to call it something like DrawingObjects (or perhaps even ActiveDrawingDatabase), if the 2nd I'd go with <MyDescriptiveNameHere>Database.
It is a place to start.It definitely is a very good place to start! Would need to extend that a bit to also allow for invoking methods. Not to mention, probably needs some inquiry functions too - to find out what object classes are available as well as what properties and the details around their methods. I'd suggest not going with the same approach as vl-dump-object, but rather use a normal LispFunction which returns a list, e.g.: A list of (<property name> . <value>) pairs for the PropertyInspect function, a list of (<method name> (<arg1 type> <arg2 type> ... <argN type>) <return type>) for the MethodInspect function. That way, if the Lisp user wanted to list these things to the text screen it would be a simple task - it just allows for much more in the shape of actually useful info for Lisp.
peter
2014-01-26, 03:19 PM
Not too sure here. Personally I don't feel that the obj prefix does anything to help, I actually think it may detract from the understanding (e.g. is it a database of objects - i.e. entities in the DWG; or is the variable an object type, just per chance containing a "database"?)
All the obj Prefix does for me is allow me to create an instance of a class with a slightly different name than the class name.
Dim objDatabase as Database
It would have been nice if the developers who named the classes would have included the name Class in their name like
DatabaseClass
so we could have had the ability to name them
Dim Database as DatabaseClass
I actually like the name Active and have a library like the AutoCAD interop files that have things like
Active.database
I suppose I could use the Class name in my names
Dim DatabaseClass as Database
I have seen the lower case first letter method. (That is my first choice after sing Reddick)
Dim database as Database
or finally
Dim dbActive as Database
Then you need to categorize all of the objects by prefix and ms frowns on the reddick naming convention prefixes now.
I actually like them and think they make my code more readable.
I absolutely do not like abbreviations in my code.
Between the Full Descriptive Names like you mentioned, lowercase first letter, or prefixes which do you prefer?
Peter
irneb
2014-01-27, 05:22 AM
It would have been nice if the developers who named the classes would have included the name Class in their name like
DatabaseClass
so we could have had the ability to name them
Dim Database as DatabaseClassThat was actually a convention with Pascal. You'd place a T prefix on the type definition, i.e. the class definition would be named something like TDatabase, then your instance variable could be just Database, and a Pointer to an instance would have a P prefix. It's not needed (as the same name rules apply as in VB/C# - letters and underscore, numbers only after first character), but most of the built-in library was done this way (especially TurboPascal and later Delphi, even these days FreePascal and Lazarus still use the same convention), so generally it was adopted as a convention. Here's the interface section (note Pascal splits the interface & implementation like C++ does, though not in seperate files) of FreePascal's standard library's Database connection class: http://www.freepascal.org/docs-html/fcl/db/tdatabase.html
Actually it's a recommended naming convention (http://msdn.microsoft.com/en-us/library/vstudio/ms229045(v=vs.100).aspx) to use small letters to start a variable's name in C#, and not use any acronyms. So for your example it's actually more accepted to use something like DatabaseObject than objDatabase (Hungarian Naming): 2 reasons - (1) obj is an acronym; (2) the word order is not as per English grammar (unless Database is the subject and Object is the "object" in the "sentence").
And this ambiguity is why I don't like including the type into the variable's name, it doesn't always happen, but when it does it confuses the hell out of me:
dbObject (I read this as DatabaseObject)
objDatabase (and this as ObjectDatabase)
But because it's Hungarian Naming I know that the prefix actually refers to the "type" - so the way I read it is probably "wrong". In both cases I'm unsure if it is a database containing objects, or a variable which is an object instance of a database class. Especially if the abbreviated prefix Hungarian Notation is used, or taken too far like in objDb or dbObj. At least when the full word is used, I can "understand" it better - at least I hope so.
irneb
2014-01-27, 05:57 AM
Actually, we're slightly missing the issue of this thread. Are we referring to how to name variables or what CLOS conventions are? Because they're a bit different from C# - seeing as CLOS works differently, a method in CLOS is more like an Extension Method in C# (well usually) in that one method definition may be applied to multiple CLOS classes without needing inheritance.
But even in Lisp it's recommended not to name variable according to their content, rather name them according to their INtent: http://google-styleguide.googlecode.com/svn/trunk/lispguide.xml#Denote_intent,_not_content
So if you want a "selectionset of lines" rather call the variable "lines" than "selectionset". I know lot's of use have done the exact opposite (myself included), but it does make a lot of sense - it conveys the purpose of the code to the reader instead of the implementation (which should be evident by the code itself already, i.e. you use ssname on the lines variable so it must contain a selection set and not a list).
The adding of type (like with Hungarian Notation or even the full grammatical naming) is basically joining the intent and the content into one name. If that's a good thing I'm not too sure, sometimes it "might be" (e.g. having a dialog with both a Username textbox and a Username drop-down-selection might require something like userNameTextBox and userNameDropDown), but I'm not convinced that it should be a convention for the general case.
peter
2014-02-17, 02:20 AM
I have decided to use the lowercase letter to designate the instances of classes.
Dim database as Database
I still like using the Hungarian notation for local numbers and strings.
strFileName, intItem, dblFactor etc...
Peter
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.