How can you be DRY with a programming language that doesn't have Reflection? [closed] - c

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
Any programming language that does not have a suitable reflection mechanism I find seriously debilitating for rapidly changing problems.
It seems with certain languages its incredible hard or not possible to do:
Convention over Configuration
Automatic Databinding
AOP / Meta programming
with out reflection.
Some example languages that do not have some sort of programmatic reflection are:
C, C++, Haskell, OCaml. I'm sure there are plenty more.
To show you can example of DRY (Don't Repeat Yourself) being violated by most of these languages is when you have to write Unit Tests. You almost always need to register your test cases in these languages outside of where you define the test.
How do programmers of these languages mitigate this problem?
EDIT: Common languages that do have reflection for those that do not know are: C#, Java, Python, Ruby, and my personal favorite F# and Scala.
EDIT: The two common approaches it seems are code instrumentation and code generation. However I have never seen instrumentation for C.
Instead of just voting to close, could some one please comment on why this should be closed and I'll delete the post.

You don't.
But you can keep the repetitions close to each other so when changing something, you see something else has to be changed too.
For example, I wrote a JSON-Parser that outputs objects, a typical call looks like this:
struct SomeStruct
{
int a;
int b;
double c;
typedef int serializable;
template<class SerializerT> void serialize(SerializerT& s)
{
s("a",a)("b",b)("c",c);
}
};
Sure, when you add a field, you have to add another field in the function, but maybe you don't want to serialize that field (something you'd have to handle in languages with reflection, too), and if you delete a field without removing it from the function, the compiler will complain.

I think it's a matter of degree. Reflection is just one very powerful method of avoiding repetition.
Any time you generalize a function from a specific case you are using DRY principle, the more general you make it the more DRY it is. Just because some languages don't get you where you get with reflection doesn't mean there aren't DRY ways of programming with them. They may not be as DRY, but that doesn't mean they don't have their own unique advantages which in total sum may outweigh the advantages of using a language that has reflection. (For example, speed consequences from heavy use of reflection could be a consideration.)
Also, one method of getting something like the DRY benefits of reflection with a language that doesn't support it is by using a good code-generation tool. In that case you modify the code for different cases once, in the code generation template, and the template pushes it out to different instances in code. (I'm not saying whether or not using code generation is a good thing, but with a good "active" generator it is certainly one way of getting something like the DRY benefit of reflection in a language that doesn't have reflection. And the benefits of code generation go beyond this simple benefit. I'm thinking of something like CodeSmith, although there are many others: http://www.codesmithtools.com/ )

Abstractly, do more at runtime, without the benefits of things like compile-time type checking (you have to essentially write your own type-checking routines) and beautiful code. E.g., use a table instead of a class. (But if you did this, why not use a dynamically-typed language instead?) This is often bad. I do not recommend this.
In C++, generic programming techniques allow you to programmatically include members of a class (is that what you want to do?) via inheritance.

One nice example for C++ unit testing is cxxtest:
http://cxxtest.tigris.org/. It uses convention and a python script to generate your C++ test suite by post-processing your C++ with python.
A good way to think about getting around restrictions in languages is Michael Feathers' notion of "seams". A seam is a place where your program can be changed without changing the code. For example, in C the pre-processor and linker provide seams. In C++ polymorphism is another place. In more dynamic languages like where you can change method definitions, or reflect, you get even more flexibility. Without the seams things can be more complicated and sometimes you just don't want to try to hammer a nail with your shoe but rather go with the flow of the tool at hand.

Related

Languages that use checked exceptions

I'm just curious, is there any other languages besides Java that uses checked exceptions ?
I did try to find information about this but couldn't find any answers.
The reason you couldn't find information on any other languages using checked exceptions is they learned from Java's mistake.
EDIT: So to clarify a little more checked exceptions were entirely a Java thing that in theory sounded like a really great idea, but in practice actually create a tight coupling between the consuming function and the function being consumed. It also makes it more tedious to handle an exception where it can be handled. Instead you have to catch and re-throw in every function in between where the exception was thrown and where it can actually be handled. I could rewrite it all here but I think this post does a magnificent job of explaining why checked exceptions are really not a good idea.
https://blog.philipphauer.de/checked-exceptions-are-evil/
Checked exceptions are not a common feature in mainstream languages due to bad experiences with them in Java. However, Java is not the only language that implements them, and just because Java's implementation was faulty does not mean that they are a bad feature in general.
Nim has checked exceptions.
Checked exceptions have been implemented as a Purescript library.
Checked exceptions can be implemented in Koka by making a custom defined effect for it.
Some common issues with checked exceptions in Java can be handled with better design.
Propogation of "throws" clauses in type signatures leading to potentially a lot of refactoring due to having to update method signatures can be solved via complete type inference. Haskell has a nice way of solving this for type classes (which propogate in the same way checked exceptions do in type signatures -- and can also be used to implement typed exceptions) with partial type signatures -- essentially leaving arbitrary parts of the type "blank" for the compiler to infer.
Issues with higher order functions/lambdas can be resolved via polymorphism/generics. In languages that implement checked exceptions via an effect system (like Koka) -- effect polymorphism is a particularly nice way to solve the problem.
Haskell, Koka, Purescript, and Nim are all highly functional languages that often make use of lambdas and higher order functions, and they don't have Java's issues with checked exceptions.

Extending MultiMap supported number of types

I'm considering extending the MultiMap methods in Dapper to support more than 5 types. Was just curious as to whether there was a technical/performance reason for 5 or was it just an arbitrary number?
It was fairly arbitrary, and due in part to some implementation particulars that make it pretty awkward to extend arbitrarily - in particular because it uses generics. Changing to an implementation that doesn't use generics would allow a more type-array based approach, but then the lambdas etc (to stitch the data back together) become pretty ugly. There are, IIRC, some pending things in the pull request queue relating to this, but I have not had much available time to review them as of yet.
Also: arguably, if you're doing a query that involves that many types, you're probably already doing something pretty complex; it is hard to expose a friendly API for arbitrarily complex systems.
Just wanted to make you aware that more types have already been supported. (Just helping you NOT reinvent the wheel)
https://code.google.com/p/dapper-dot-net/issues/detail?id=50
At the bottom of the page you can get a git-hub change.
Matt

What impact does using these facilities have on orthogonality?

I am reading The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt, David Thomas. When I was reading about a term called orthogonality I was thinking that I am getting it right. I was understanding it very well. However, at the end of the chapter a few questions were asked to measure the level of understanding of the subject. While I was trying to answer those questions to myself I realized that I haven't understood it perfectly. So to clarify my understandings I am asking those questions here.
C++ supports multiple inheritance, and Java allows a class to
implement multiple interfaces. What impact does using these facilities
have on orthogonality? Is there a difference in impact between using multiple
inheritance and multiple interfaces?
There are actually three questions bundled up here: (1) What is the impact of supporting multiple inheritance on orthogonality? (2) What is the impact of implementing multiple interfaces on orthogonality? (3) What is the difference between the two sorts of impact?
Firstly, let us get to grips with orthogonality. In The Art of Unix Programming, Eric Raymond explains that "In a purely orthogonal design, operations do not have side effects; each action (whether it's an API call, a macro invocation, or a language operation) changes just one thing without affecting others. There is one and only one way to change each property of whatever system you are controlling."
So, now look at question (1). C++ supports multiple inheritance, so a class in C++ could inherit from two classes that have the same operation but with two different effects. This has the potential to be non-orthogonal, but C++ requires you to state explicitly which parent class has the feature to be invoked. This will limit the operation to only one effect, so orthogonality is maintained. See Multiple inheritance.
And question (2). Java does not allow multiple inheritance. A class can only derive from one base class. Interfaces are used to encode similarities which the classes of various types share, but do not necessarily constitute a class relationship. Java classes can implement multiple interfaces but there is only one class doing the implementation, so there should only be one effect when a method is invoked. Even if a class implements two interfaces which both have a method with the same name and signature, it will implement both methods simultaneously, so there should only be one effect. See Java interface.
And finally question (3). The difference is that C++ and Java maintain orthogonality by different mechanisms: C++ by demanding the the parent is explicitly specified, so there will be no ambiguity in the effect; and Java by implementing similar methods simultaneously so there is only one effect.
Irrespective of any number of interfaces/ classes you extend there will be only one implementation inside that class. Lets say your class is X.
Now orthogonality says - one change should affect only one module.
If you change your implementation of one interface in class X - will it affect other modules/classes using your class X ? Answer is no - because the other modules/classes are coding by interface not implementation.
Hence orthogonality is maintained.

How do I adapt the look and feel of existing Tk apps using TTk?

slebetman says:
But Tk is only really ugly on Unixen because it defaults to a Motif theme (modern Tk is/should be replaced by TTk which is themeable).
Given two Tk apps which I still use occasionally, namely Gitk and ptkdb, how do I change their look and feel so that it matches the rest of the desktop environment (KDE 4)?
See: http://wiki.tcl.tk/gtklook.tcl for a quick way to make default Tk look less painfully ugly. I often use it in my own programs to hide the fact that it's actually written in tcl/tk.
The code given is tcl but you can easily use the options in an Xresources or Xdefaults file which I think should work in other languages as well. Or, it that doesn't work I believe there is an equivalent option method in Perl/Tk*.
Yes, the changes are not much. Basically just reducing pixel widths of things like borders and scrollbars. But it does look much nicer.
*note: I only mention Perl/Tk because you mentioned it in another post. As for modifying gitk, it is written in tcl so you can easily copy-paste the code somewhere.
Check out the TkDocs website, everything I know about modern Tk I learnt from there! Well and experience too of course ;-)
It will not be simple to retrofit it onto a substantial legacy application, but you could probably get surprisingly far by just prefixing the widgets with ttk::.

How to create a smart chat-bot? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I know that it's still an open problem so I don't expect to see complete answers here. I just want to find some approaches to solve the next problem:
I have a model (assume that is's bot's memory), and different words are associated with different objects in the model. Speaking with the bot is like executing sql-queries with a DB. Language is a very hard formalizable protocol. And we can't just write a million lines of code to implement some real language. But I believe that it's absolutely possible to implement some self-learning mechanism. How can it be implemented? Is it possible to implement learning "from scratch" or "from few basic words"? Just want to hear your ideas.
Actually, English is a very strict language and it's one of the easiest languages for experimenting with AI. Many other languages allow you to change the order of words (for example). And in some cases changed order can change the whole meaning or just add some intonation. I really don't have any ideas how to teach a bot for these things.
The first step, in taking this game to the next level, is ...
...to have a very clear view of prior art!
(and pardon me to say, the question doesn't suggest that you have such an extensive insight into the matter [and you're not alone, count me in ;-)])
Even, and maybe in particular, if your intention is to apply completely novel techniques and models, it seems important to review the literature on current and past practices. Aside from possibly identifying elements that may be adapted or reused in a new implementation, a survey of the domain will provide an keen understanding of the nature of the problem[s].
I've personally tried -on various and multiple occasions!- either the naive approach or the sophomoric approach to tackling broadly-defined problems. With the naive approach, one has but a very slight idea of the true nature and scope of the problem. The sophomoric sees us better equipped with domain knowledge and also with related tools, but this can also be misleading because without a deeper understanding, we tend to mis-read/mis-understand new material offered to us and also misuse some of the tools (a bit like the the fellow who's "good with a hammer" for whom many things look like a nail...)
It is particularly easy to make these mistakes in the field of NLP. That's because
Common sense seems to be all is required: after all a child, who's native tongue is English understands subtleties like
"He's not really an expert"
"He's really not an expert" (small wink at the OP's reference to the ordering of word in the English language)
We live in such exciting times, technology and knowledge wise: Processing power, programming language and tools, mathematical techniques, availability of affordable corpora... to name a few of these things that make this moment in time so special.
Far from me the idea of discouraging you in your chat-bot endeavor, I just hope that this long and generic exposé will encourage to look-before-you-leap, as this will truly save you time in the long run, I think in two ways:
provide you some frames of references (again, even if your intention is to "think outside these boxes")
maybe entice you to redefine the problem, for example by limiting it to particular domains of conversation (sports, or health, or life at a particular university campus...) or by focusing on a particular aspect of the problem (semantic awareness, smooth, natural sounding grammar, use of colloquial forms...)
Good luck ;-)
Check out MegaHAL's implementation for some ideas. We've used a variant of this bot for ages in an IRC channel of ours, and he does on occasion appear to be the intelligent mixture of many of our dominant personalities.
You "train" the bot -
each time the bot answer, you rank (or the tester) the answer - if the answer is good/logical - give high rank, if the answer is bad... low/negative rank.
use the ranking in the future to choose the answer, and this is how the bot learns...
There's a great description of Eliza in Paradigms of AI Programming. You should be able to implement a simple Eliza bot in a few days of work.
This isn't a learning algorithm, but it's surprising how realistic answers can be from something so simple.
You can create your own chat bot on BOT libre, http://www.botlibre.com.
The bots learns, can be trained, can be scripted, and your can program them, or let them program themselves.
Thew site supports embedding your bot on your own site, has REST API access, Android, IRC, Twitter. Free hosting, even for commercial bots.
AIML from the AliceBot project may help you out. It's a whole XML schema (if that doesn't put you off) for the branch of AI its concerned with.
An example from Wikipedia:
<category>
<pattern>WHAT IS YOUR NAME</pattern>
<template>My name is <bot name="name"/>.</template>
</category>
RebbeccaAIML is one quite well documented implementation.

Resources