diff --git a/libwccl/ops/constant.h b/libwccl/ops/constant.h
new file mode 100644
index 0000000000000000000000000000000000000000..abb08e9b505fd0c0ef47e4c7916fad9a21d2943a
--- /dev/null
+++ b/libwccl/ops/constant.h
@@ -0,0 +1,60 @@
+#ifndef CONSTANT_H
+#define CONSTANT_H
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/concept_check.hpp>
+
+#include <libwccl/ops/functions.h>
+
+namespace Wccl {
+
+
+/**
+ * Functional realisation of constant value of a given type
+ */
+template<class TRet>
+class Constant : public Function<TRet> {
+	BOOST_CONCEPT_ASSERT((boost::CopyConstructible<TRet>));	
+public:
+	/*
+	 * Constant function holds specific value to return when applying it
+	 */
+	Constant(const TRet& value)
+		: value_(new TRet(value))
+	{
+		BOOST_ASSERT(value_);
+	}
+	
+	/**
+	 * Operator name for constant is string representation of its value
+	 */
+	virtual const std::string operator_name(const Corpus2::Tagset& tagset) const {
+		return value_->to_string(tagset);
+	}
+
+	/**
+	 * Operator name for constant is string representation of its value,
+	 * tagset-independent in this case
+	 */
+	virtual const std::string raw_operator_name() const {
+		return value_->to_raw_string();
+	}
+
+protected :
+	typedef FunctionBase::BaseRetValPtr BaseRetValPtr ;
+
+	/**
+	 * Applying Constant function returns the held value of a constant
+	 */
+	virtual BaseRetValPtr  apply_internal(const SentenceContext&) const {
+		return BaseRetValPtr (new TRet(*value_));
+	}
+
+private:
+	const boost::scoped_ptr<const TRet> value_;
+};
+
+
+} /* end ns Wccl */
+
+#endif // CONSTANT_H
diff --git a/tests/constant_tests.cpp b/tests/constant_tests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..59f52aa053dea629078288f594612144f5a2542e
--- /dev/null
+++ b/tests/constant_tests.cpp
@@ -0,0 +1,69 @@
+#include <boost/test/unit_test.hpp>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <libwccl/ops/constant.h>
+#include <libwccl/variables.h>
+#include <libwccl/values/bool.h>
+#include <libwccl/sentencecontext.h>
+
+
+using namespace Wccl;
+
+BOOST_AUTO_TEST_SUITE(constant)
+
+struct BoolFix
+{
+	BoolFix()
+		: sc(boost::make_shared<Corpus2::Sentence>()),
+		  tagset(),
+		  true_value(true),
+		  false_value(false),
+		  true_constant(true_value),
+		  false_constant(false_value)
+	{
+	}
+	SentenceContext sc;
+	Corpus2::Tagset tagset;
+
+	Bool true_value;
+	Bool false_value;
+	Constant<Bool> true_constant;
+	Constant<Bool> false_constant;
+};
+
+BOOST_FIXTURE_TEST_CASE(bool_apply, BoolFix)
+{
+	BOOST_CHECK_EQUAL(true, true_value.get_value());
+	BOOST_CHECK_EQUAL(true, true_constant.apply(sc)->get_value());
+	BOOST_CHECK_EQUAL(false, false_value.get_value());
+	BOOST_CHECK_EQUAL(false, false_constant.apply(sc)->get_value());
+}
+
+BOOST_FIXTURE_TEST_CASE(bool_to_string, BoolFix)
+{
+	BOOST_CHECK_EQUAL("true", true_value.to_string(tagset));
+	BOOST_CHECK_EQUAL(true_value.to_string(tagset), true_constant.to_string(tagset));
+	BOOST_CHECK_EQUAL("false", false_value.to_string(tagset));
+	BOOST_CHECK_EQUAL(false_value.to_string(tagset), false_constant.to_string(tagset));
+}
+
+BOOST_FIXTURE_TEST_CASE(bool_to_raw_string, BoolFix)
+{
+	BOOST_CHECK_EQUAL("true", true_value.to_raw_string());
+	BOOST_CHECK_EQUAL(true_value.to_raw_string(), true_constant.to_raw_string());
+	BOOST_CHECK_EQUAL("false", false_value.to_raw_string());
+	BOOST_CHECK_EQUAL(false_value.to_raw_string(), false_constant.to_raw_string());
+}
+
+BOOST_FIXTURE_TEST_CASE(bool_value_preserved, BoolFix)
+{
+	boost::shared_ptr<Bool> v = true_constant.apply(sc);
+	v->set_value(false);
+	BOOST_CHECK_EQUAL(true, true_constant.apply(sc)->get_value());
+	v = false_constant.apply(sc);
+	v->set_value(true);
+	BOOST_CHECK_EQUAL(false, false_constant.apply(sc)->get_value());
+}
+
+BOOST_AUTO_TEST_SUITE_END()