As an ArgoUML contributor I'm going to blog my activities here, so that they may draw interest by other developers or help other developers when doing tasks similar to what I've done. AND(!) the grand vision that makes an Argonaut what he is, TO THRIVE IN THE BIG DANGEROUS WORLD, TAKING THE Argo TO A GOOD SHORE ;-))

Saturday, June 26, 2010

ArgoUML C++ – generator and modeling

The C++ code generator in the ArgoUML C++ module has been growing in its usage of Taggedvalues and it hasn't grown more because it hasn't received recent contributions. In a recent thread in the Using ArgoUML for modeling C++ topic of the ArgoUML's users forum, this started to become more clear for me. Here is my answer to Ulrich Thombansen's on the 24th of June:

Hi Ulrich,

> (...) on the “constructor”. What about taking this off the documentation at tigris?

I consider that the best solution. Given two ways to make something, I would go for the standard UML way, which even if taking a bit more of work by the user, it is more flexible because you have an actual operation that might be customized, e.g., by adding arguments. By being explicit we may in the future enable specific customization related to C++ constructor specificity.

Note to self: TODO: place this conclusion in the issue 21. Consider the possibility of some TagDefinitions in the «cppOperation» Stereotype being only applicable if the Operation to which the Stereotype is applied also has the «create» Stereotype applied.

> cppAttribute
> ==========
> applying «cppAttribute» to a variable “myAttrib” with the tag “pointer” set to different values leads to the following results:
> no) tag value -> result
> ----------------------------
> 1) “false” -> int myAttrib; /*{pointer=false}*/
> 2a) “true” -> int *myAttrib; /*{pointer=true}*/
> 2b) “xyz” -> int *myAttib; /*{pointer=xyz}*/
> 3) “” -> int *myAttib;
>
> Feature or fault?

IMO feature (I would call it a default behavior due to a present limitation in ArgoUML) and a nicely chosen one, although in the future when ArgoUML supports typed TaggedValues, I would model the “pointer” TagDefinition as a UML Boolean and therefore you would only have True or False. The rational behind letting the user model any “pointer” TaggedValue as being true but the actual String “false” is that if the user added the “pointer” TaggedValue in an Attribute, it is because he want the pointer to be present.

> cppAttribute
> ===========
> applying «cppAttribute» to a variable “myAttrib” with the tag “get” set to public leads to the implementation of the int get_myAttrib(); function.
>
> Is there a way to make this “virtual”? GeneratorCpp.java only creates “virtual” for (!leaf && !isConstructor && !static)||abstract. Which rule applies / can be influenced?

This is one of the reasons I dislike TaggedValues being used where the default UML suffices. By adding the “get” or “set” TaggedValues to represent an hint for the generator you put yourself in a position where you step out of the proper language for representation of the Operations. If there was a button for generating get and set operations for a given attribute at the model level you would have afterward the liberty to customize it as for any other operation. Since ArgoUML doesn't have this, we added “get” and “set” TagDefinitions to the «cppAttribute» Stereotype, but, given that these are simply TaggedValues we will be left with the modeling of all the particularities of operations as different values of the “get” and “set” TaggedValues. It isn't a fair deal. The overload isn't only for the implementation, but, also for the users...

I would model it the other way around, having a “get” and “set” TagDefinitions applicable to Operations to which the «cppOperation» is added and the values would have to match the name of the attribute which the operations are related to. A more powerful way would be an association between the Operations and the Attributes, but, I don't know if UML allows that, and I'm almost certain that ArgoUML doesn't.

One of the issues with all this is trying to guarantee symmetry between code generation and reverse engineering. Although it is a bit like utopia, we might be closer to it if we stick as much as possible within the UML proper when possible.

Note to self: TODO: create an issue of type enhancement proposing the deprecation of get and set TagDefinitions in «cppAttribute» and adding the these TagDefinitions to «cppOperation». Model it initially as a String that must match the corresponding Attribute name and afterward as an Association (if and when this is supported).

Friday, June 25, 2010

Dispersion problem – revisited after 7 months

About 7 months ago I wrote about my dispersion problem. I didn't honored my decision at that time which was to dedicate myself fully to ArgoUML during about one year. For instance, I recently finished some hacking in the friendly user interface for htmled that allows me to say:

python hb2post.py --startdate=2010-06-01 > posts-in-programacao-since-june-1st.txt

Why did I did it? It isn't only dispersion working, it is also a desire to be a better hacker and to know more. But, this takes me away from my dream which is to fulfill one or more remarkable ideas. So, back to initial plan.

But, to see the glass half full instead of half empty, I list all the issues I was involved with in ArgoUML and which are resolved since my decision:

Also, looking in retrospective the past months were good for ArgoUML on several areas:

  • Linus Tolke finally handled the switch of the ArgoUML license from BSD like to the Eclipse Public License (EPL) 1.0, which means that ArgoUML and ArgoEclipse will move together and that Tom Morris will be more willing to continue to contribute.
  • Bob Tarling was the main contributor to ArgoUML 0.30.1 and he was able to achieve the replacement of the old model elements property panels by the new implementation which is based on XML definitions. Originally this was developed by Christian López Espínola in a GSoC 2008 project, but, never before matured enough to be a full and stable replacement of the old implementation. Kudos to Bob :-)
  • Tom Morris returned to active ArgoUML contributions, and although he isn't yet as active as before, his overall understanding and detailed knowledge of UML and plenty of ArgoUML components helps a lot when others need guidance such as I did during 0.30.x bug fixing period. In the last period of 0.30.1 development, he even took issue 6008 on his hands and made some big changes to the reference handling of profile model elements which I would have struggled for months to get right. He achieved it in about one week.
  • Linus Tolke managed to stabilize the Hudson continuous integration server where ArgoUML nightly builds are executed and continues to maintain the automated builds, project infrastructure and release tasks.
  • Thomas Neustupny and Andreas Rueckert are actively evolving the argouml-core-model-euml implementation of the model subsystem (the result of a GSoC 2007 project by Bogdan Ciprian Pistol) and therefore moving ArgoUML towards UML 2.x.
  • I'm happy with the progressive stabilization and polishing of the profile subsystem (yet another result of a GSoC 2007 project, this one by Marcos Aurélio).
  • ArgoUML's users forum is growing in activity with Thomas Neustupny, Tom Morris, me, daybyter and KiwiCoder being active helpers. Kudos to Lukasz Gromanowski for setting this and the users' wiki for the project and for the continued support. Compared with the argouml-users mailing list the forum is rocking!
  • Michiel Van der Wulp continued to support the notation subsystem and the state and activity diagrams and although he isn't so actively contributing as he used to he continues to help with his expertise in these areas.
  • There was also the return of previously inactive contributors such as Alexander Lepekhine.

I may be forgetting some relevant contribution and if so drop me a line to update this post. I think that attributing the kudos to contributors is important for the health of the project. Thank you all for continuing to move forward the project and to our users to keep nagging us about the bugs and annoyances :-)

Tuesday, June 15, 2010

Learning Clojure – development environment configuration

I already started learning Clojure some time ago by following the tutorial Clojure - Functional Programming for the JVM by R. Mark Volkmann, a Partner of Object Computing, Inc. (OCI). I also did the casting Clojure tutorial, read a lot of Clojure blog posts and saw some videos about Clojure.

What I was missing was a sane Clojure development environment configuration which could live at peace with my Common Lisp Emacs SLIME development environment. Well, by following the Swank_clojure_setup_for_hardcore_Emacs_users.el I achieved it. But, first I had to ditch my Debian based SLIME installation and go to the SLIME CVS version. That was the base recommendation that hardcore Emacs and Common Lisp hackers give, so, nothing too wild here.

Besides Clojure, I also wanted to have working Common Lisp implementations connected to Emacs. My choice was previously the SBCL version available from Debian repositories and ABCL from the Subversion checkout.

So, enough introduction, follows the objectives and how I did it on a Debian based GNU/Linux distribution and bash.

  • Emacs snapshot from Debian's repositories.
    ~$ sudo apt-get install emacs-snapshot-gtk emacs-snapshot-el
     
  • SLIME from CVS.
    ~$ sudo apt-get install cvs # only if you don't have CVS yet
    ~$ cd programacao/lisp # I have all Lisp related programming sources here
    ~/programacao/lisp$ cvs -d :pserver:anonymous:anonymous@common-lisp.net:/project/slime/cvsroot co slime
    ~/programacao/lisp$ cd slime/doc
    ~/programacao/lisp/slime/doc$ sudo apt-get install texlive # because I want to build an up-to-date slime-doc
    ~/programacao/lisp/slime/doc$ make
    ~/programacao/lisp/slime/doc$ gzip slime.info # TODO: this is available as make install, but, my distribution paths are different...
    ~/programacao/lisp/slime/doc$ sudo install-info slime.info # make it available to info
    ~/programacao/lisp/slime/doc$ sudo cp slime.info.gz /usr/share/info/
    ~/programacao/lisp/slime/doc$ cd ~
     
  • SBCL from source tarball download, which I placed in ~/programacao/lisp/sbcl.
    ~$ cd programacao/lisp/sbcl
    ~/programacao/lisp/sbcl$ tar -xvjf sbcl-1.0.39-source.tar.bz2
    ~/programacao/lisp/sbcl$ cd sbcl-1.0.39/
    Now, check the INSTALL...
    Now, check the Getting started...
    I already had the SBCL from Debian, so, this would be my Common Lisp host which would be automatically used by make.sh.
    ~/programacao/lisp/sbcl/sbcl-1.0.39$ sh make.sh # and detach with C-a d, using screen -r to check its state from time to time
    An alternative I will try next time is to use a non-GUI terminal by going C-M-F1.
    TODOs: install binaries, build and install doc.
    ~/programacao/lisp/slime/doc$ cd ~
     
  • ABCL from Subversion. I already had Subversion and Ant installed via apt-get install.
    ~$ mkdir -p programacao/lisp/abcl/svnco && cd programacao/lisp/abcl/svnco
    ~/programacao/lisp/abcl/svnco$ svn co svn://common-lisp.net/project/armedbear/svn/trunk/abcl && cd abcl
    ~/programacao/lisp/abcl/svnco/abcl$ ant # this creates the abcl executable shell script to launch ABCL
    ~/programacao/lisp/abcl/svnco/abcl$ cd ~
     
  • Ant and Maven binaries downloaded and installed.
    ~$ sudo apt-get install maven2
     
  • Clojure and Clojure-contrib from their Git repositories. Git was already installed.
    ~$ cd programacao/clojure
    ~/programacao/clojure$ git clone http://github.com/richhickey/clojure.git
    ~/programacao/clojure$ git clone http://github.com/richhickey/clojure-contrib.git
    ~/programacao/clojure$ cd clojure
    ~/programacao/clojure/clojure$ ant jar
    ~/programacao/clojure/clojure$ cd ../clojure-contrib
    ~/programacao/clojure/clojure-contrib$ mvn package
    ~/programacao/clojure/clojure-contrib$ cp target/clojure-contrib-*.jar clojure-contrib.jar
    ~/programacao/clojure/clojure-contrib$ cd ~
     
  • Leiningen binary downloaded and installed.
    ~$ mkdir -p progs/lein && cd progs/lein/
    ~/progs/lein$ wget http://github.com/technomancy/leiningen/raw/stable/bin/lein && chmod u+x lein
    ~/progs/lein$ cat >> ~/.profile
    PATH="$PATH:$HOME/progs/lein"
    # finish editing with C-d

    ~/progs/lein$ lein self-install
    ~/progs/lein$ cd ~
     
  • Clojure-mode and Swank-clojure also from Git repositories.
    ~/programacao/clojure$ git clone http://github.com/technomancy/clojure-mode.git
    ~/programacao/clojure$ git clone http://github.com/technomancy/swank-clojure.git
    ~/programacao/clojure$ cd swank-clojure && lein jar
    ~/programacao/clojure/swank-jar$ cd ..
     
  • Create a shell script to launch Clojure with all the required goodies in the classpath. Note that this script will be used within Emacs and therefore you don't want fancy wrapping and history with rlwrap. You may create one of those to use in the command line, though.
    ~/programacao/clojure$ cat > clj-dev.sh
    #!/bin/sh
    CLOJURE_JAR=/home/user/programacao/clojure/clojure/clojure.jar
    CLOJURE_CONTRIB_JAR=/home/user/programacao/clojure/clojure-contrib/clojure-contrib.jar
    SWANK_CLOJURE_JAR=/home/user/programacao/clojure/swank-clojure/swank-clojure.jar
    JAVA=$(which java)
    CLJ="$JAVA -server -cp $CLOJURE_JAR:$CLOJURE_CONTRIB_JAR:$SWANK_CLOJURE_JAR clojure.main"
    exec $CLJ "$@"
    # not part of the file, finish with C-d

     

So, after writing all this in shell language, would it be possible to have it in Clojure, Common Lisp or Emacs Lisp? With Clojure we could get fancy and execute some long lasting tasks in parallel.

Finally, the relevant part of my ~/.emacs file:

;;; SLIME and Lisp and Clojure support
(require 'cl)
(add-to-list 'load-path "~/programacao/lisp/slime/")
(setq slime-backend "swank-loader.lisp")
(setq inferior-lisp-program "~/programacao/lisp/sbcl/sbcl-1.0.39/run-sbcl.sh")
(add-to-list 'load-path "~/programacao/clojure/clojure-mode/")
(add-to-list 'load-path "~/programacao/clojure/swank-clojure/")
(pushnew '("\.clj$" . clojure-mode) auto-mode-alist)
(require 'clojure-mode)
(setq slime-lisp-implementations
      '((sbcl ("~/programacao/lisp/sbcl/sbcl-1.0.39/run-sbcl.sh"))
 (abcl ("~/programacao/lisp/abcl/svnco/abcl/abcl") :coding-system iso-latin-1-unix)
 (clojure ("~/programacao/clojure/clj-dev.sh") :init swank-clojure-init)))
(require 'slime-autoloads)
(setf slime-use-autodoc-mode nil) ; swank-clojure doesn't support autodoc-mode
(slime-setup '(slime-banner slime-repl slime-fancy slime-scratch
       slime-editing-commands slime-scratch slime-asdf))
(setf slime-net-coding-system 'utf-8-unix)
(setf swank-clojure-binary "~/programacao/clojure/clj-dev.sh")
(require 'swank-clojure)
(defun run-clojure ()
  "Runs clojure lisp REPL"
  (interactive)
  (slime 'clojure))
(defun run-abcl ()
  "Runs ABCL lisp REPL"
  (interactive)
  (slime 'abcl))

I still have Paredit configured for the Lisp dialects I use, which is another recommended way to customize Emacs. Definitely, there are pieces missing, but, I reached a target with enough relevancy for me to be worthy of careful documentation :-) I could have earned extra hacking points if it would be automated, though, so, thou shall not halt here!

Reader Shared items

Followers