6

Are there any languages where something like the following might be possible?

people = [ ... a list of people ...]
Person jake = Person("Jake", 165, ...)
jake is Tall
people.add(jake)
for Person person in people where Tall:
    // ... do something terrible to them
jake is not Tall // ... Jake no longer wishes to be tall

I hope that makes sense - basically, dynamic adjectives that affect something about an object's properties or methods.

8
  • This is easily simulated in a language like ruby with the appropriate method_missing Jul 17, 2013 at 23:02
  • 1
    @jozefg Could you provide an example? There are probably ways to do it in all languages but I wouldn't want to see the Java reflection example, for instance.
    – sdasdadas
    Jul 17, 2013 at 23:06
  • 1
    Most language that allows for the creation of a DSL within the language itself could do this. A language such as perl where you can rewrite it to latin could fairly easily add additional constructs to the language to make use of adjectives. Similarly any language where the language itself is is a first class data type within the language (Lisp and Forth being the best example) could do this.
    – user40980
    Jul 17, 2013 at 23:42
  • 4
    at first glance, I misread title as "Are there any programming languages that make use of expletives?"
    – gnat
    Jul 18, 2013 at 1:08
  • 1
    From a pythonic point of view, that last line looks like a list comprehension, IE [p for p in people if p is tall]
    – jackweirdy
    Jul 18, 2013 at 11:48

9 Answers 9

12

Adjectives are really just attribute evaluation. Here's how I might handle it in JavaScript.

function PersonAdjectiveConstructor(person) {
    this.isTall = (person.height >= 6);
    this.isRich = (person.pocketMoney >= 1000000);
    this.isSmart = (person.iq > person.shoeSize);
    this.isInsufferable = ( this.tall && this.rich && this.smart );
    //formerly (for comment context):
    //this.isInsufferable = ( this.smart && this.rich && this.smart );
}

function PersonConstructor(personAttributes){

    for(var x in personAttributes){
        this[x] = personAttributes[x];
    }    

    var adjectives = new PersonAdjectiveConstructor(this);

    for(var x in adjectives){
        this[x] = adjectives[x];
    }
}

var bob = new PersonConstructor({ shoeSize:11, iq:12, height:6.25, pocketMoney:2000000 });

console.log(bob.isInsufferable);//true
10
  • 2
    I wasn't necessarily thinking only attribute evaluation - for example, take the attribute Winged. That might give its possessor the fly() method.
    – sdasdadas
    Jul 18, 2013 at 0:08
  • this.fly = function(){ if( this.isWinged && !this.isFat ){ ... } }; Jul 18, 2013 at 0:19
  • or this.fly = ( this.isWinged && !this.isFat ) ? function(){...} : null; Jul 18, 2013 at 0:20
  • 1
    Writing an else condition in for the first one would be the part I'd enjoy. Jul 18, 2013 at 0:22
  • 2
    Hint: if you put <!-- language: lang-javascript --> before your code block, it will highlight it for javascript. See Manually specify language for syntax highlighting for the language list and Language hint for the code environment for a better demonstration of how to use it.
    – user40980
    Aug 6, 2013 at 17:08
24

Prolog and other logic programming languages do this. They have identifiers with lists of characteristics which are then queried to do computation. Inferences about relationships can also be made.

This example from Wikipedia shows how:

mother_child(trude, sally).

father_child(tom, sally).
father_child(tom, erica).
father_child(mike, tom).

sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).

parent_child(X, Y) :- father_child(X, Y).
parent_child(X, Y) :- mother_child(X, Y).

So you've described some family relations here. You can then ask Prolog a question about them:

?- sibling(sally, erica).
Yes
3
  • Thanks for the reply - I'd forgotten about Prolog. Ideally, the language would be of the imperative sort (for my own preference). But this answers the question and if no more trickle in, I'll accept it.
    – sdasdadas
    Jul 17, 2013 at 23:04
  • As I understand it though, you cant change facts midway through computation, he made it sound like he wants dynamic traits, eg: married(sally, jim)... divorce(sally,jim)... Jul 17, 2013 at 23:27
  • @jozefg Yes, dynamic traits. Also, since I may have been unclear - this doesn't necessarily have to relate to boolean variables (or variables at all). An adjective could describe the functions of an object, as well. Similar to interfaces, I suppose, but the adjective would implement the method - as opposed to Java where the child of the interface implements it.
    – sdasdadas
    Jul 18, 2013 at 0:10
12

Inform 7 is a natural-language programming language, heavily geared towards writing interactive fiction.

It has a rich variety of ways to express and use adjectives:

  • Simple two-state attributes: "John is sunburnt."
    • Inform will automatically understand the opposite of this to be "not sunburnt". You can specify both labels though: "A person can be tall or short. John is tall."
  • Enumerations (what Inform calls "kinds of value"): "Colour is a kind of value. The colours are red, green and blue. The box has a colour. The box is blue."
  • Rule-based definitions for computing whether an adjective applies: "Definition: a thing is heavy if its weight is greater than 10kg." Alternatively: "Definition: a thing is heavy rather than light if its weight is greater than 10kg."

Having defined these adjectives, there are many ways to use them, and they're understood both by the compiler and by the runtime parser accepting user input. Some simple examples:

  • Assign them to objects: "Now the box is red."
  • Test for their presence: "If the person is short..."
  • Discriminate between objects to which the same adjective could apply: "If the heaviest box is red..."

With apologies to the writers of Inform documentation for any examples I might unwittingly have borrowed. I imagine things like weight and colour crop up often :P

8
  • That's really cool, thanks! (It's just a shame their server seems to be down.)
    – sdasdadas
    Jul 18, 2013 at 2:57
  • "Usually" used for writing IF? Any examples of using it for other stuff? Jul 19, 2013 at 1:11
  • @SeanMcSomething Good point; I don't know why I have a vague memory of seeing it twisted to other uses. Answer updated. Jul 19, 2013 at 9:05
  • 1
    @shambulator drat. I was hoping to see something horrific, like a web server written in I7. Jul 19, 2013 at 20:24
  • 1
    No and now I think about it these were probably I6 rather than I7, the LISP tutorial was pretty cool though IIRC it was 'taught' by a genie
    – jk.
    Jul 26, 2013 at 9:20
3

Applescript seems to be a good candidate.

Here are some examples, excerpt from AppleScript: Beginner's Tutorial:

tell application "Finder" to open the startup disk

tell application "Finder" to set the current view of the second Finder window to flow view

tell application "QuickTime Player" to set the current time of the front document to 94900
2

Your "adjectives" are basically just boolean attributes, which pretty much every programming language has, and your filter operatio is, well, a filter operation which any halfway decent collection framework has.

For example, in Ruby:

class Object
  def is(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do true end end
  end

  def isnt(*attrs)
    attrs.each do |attr| define_singleton_method(:"#{attr}?") do nil end end
  end
end

Person = Struct.new(:name)

jake = Person.new('Jake')
bill = Person.new('Bill')

jake.is(:tall, :mean)
bill.isnt(:tall)
bill.is(:mean)

people = [jake, bill]

people.select(&:tall?)
# => [#<struct Person name="Jake">]

people.select(&:mean?)
# => [#<struct Person name="Jake">, #<struct Person name="Bill">]

jake.isnt(:mean)

people.select(&:mean?)
# => [#<struct Person name="Bill">]

Maybe if you describe the actual problem you are having, you will get better answers, but for now, standard collection operations and a simple boolean attribute are plenty enough; there doesn't seem to be anything that requires sophisticated inference, backtracking, unification or anything like that.

2
  • 5
    Is curiosity a problem?
    – sdasdadas
    Jul 18, 2013 at 0:03
  • Just to extend my snide remark, the reason I asked this question is because I was reading about English grammar. Two fundamentals of grammar seem to be covered (nouns and verbs) by different paradigms. But there are a few aspects of grammar that don't (yet?) have a paradigm attached to them, it would seem.
    – sdasdadas
    Jul 18, 2013 at 17:35
1

Ok ruby answer:

module Traity
  def initialize
    @traits = {}
  end
  def method_missing trait
    @traits[trait]
  end
  def give_trait trait
      @traits[trait] = true
  end
  def take_trait trait
      @traits[trait] = false
   end
end

class Tom
   include Traity
end

 t = Tom.new
 t.give_trait :tall
 puts t.tall
 t.take_trait :tall
 puts t.tall
1

I think that you could view modifiers on declarations as adjectives.

For instance:

    static int foo;

says "We declare foo to be a static int". The word static an adjective, both in the Java context and in the English language.


Another example is Java annotations.

Note that since annotations can be user-defined, you have user-defined adjectives.


Java is a statically compiled language so it doesn't have dynamic adjectives in the broadest sense. However, you could generalize this "analysis" to any (dynamic) language with these language features.

I'm not convinced it is particularly useful though. The mere possibility of adjectival constructs is not sufficient. You also need significant (application specific) support to make the constructs do something useful. (For instance, in Java you need either application specific annotation processors or reflective code in the application to examine annotations at runtime.)

1

Firstly, that looks like Python.

Secondly, things like Tall aren't necessarily reflexive. Lets assume as a part of our syntax:

  • is can be an infix operator that and sets an object attribute, eg. Jake is Tall makes Jake.Tall True
  • is can be a prefix operator that queris the precence of an attribute.
  • Being over 185cm is tall

So lets begin:

Jake <= Person(name="Jake")
Jake is Tall
print(is Jake Tall)
>>> True

All is well, but this introduces problems.

print(Jake.height)

We know Jake is tall, but how tall is he?

Even again:

Jake <= Person(name="Jake",height=199)
Jake is Tall
print(is Jake Tall)

What do we print here? Now, we've said Jake is less than 200cm, so he isn't Tall, but he've also explicitly stated that he is tall. We can start to introduce logic so that when we call Tall against a person we check the Tall state or the height attribute, but the logic incongruencies are difficult.

What you can do is similar to what Python does with its is statement, and use it to check a state, rather than set it.

So we could go:

Jake <= Person(name="Jake",height=199)
if Jake is Tall {
    print("How is the weather up there?")
} else {
    print("Need a ladder?")
}
>>> Need a ladder?

This syntax could then just be a shorthand of Jake.isTall or any number of attribute checkers.

1
  • I was more assuming that adjectives would actually redefine parts of objects - for instance the object button might have only one attribute, button.text. If we state button is Selectable, then the language might add the property isSelected to the button, as well as the methods click, hide, and blink. So it's not so much that an adjective would only be a property - rather it would be a mini-object of sorts that changes the functionality depending on which object it is assigned to.
    – sdasdadas
    Jul 18, 2013 at 2:45
1

From some of your comments, I think Scala's Traits are a good candidate. They are basically interfaces which can contain implemented methods and can be used in lots of nice ways.

For example having a trait and a class:

trait Foo {
  def bar = println("I'm a thing that's Foo, which means I can Bar")
}
class Doodle {}

Will let you execute a series of statements:

var foodoodle = new Doodle with Foo
foodoodle.bar

Which executes bar, printing "I'm a thing that's Foo, which means I can Bar".

This kind of addresses your comment about a "Winged" property giving an object a fly() method.

1
  • Yes! That works how I would expect it to work. The only problem is that they can't be removed at runtime (from what I've read, please correct me if I'm wrong). Thanks very much for this though, I'm going to read more about Scala's traits!
    – sdasdadas
    Jul 18, 2013 at 17:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.